小弟接触逆向领域掰着手指头算下来也得有断断续续的三年了,最近找到一个不错的实习机会,关于C++逆向的,主要领域是反外挂和防盗号。
虽然相对其他人有些基础,但心里还是没有底…为啥呢,因为这三年来自己一直都是遇到问题想着怎么用其他的办法去代替它从而达到“解决”这个问题的目的,(俗称馊主意 ─=≡Σ(((つ•̀ω•́)つ),但是没有静下心来好好斟酌过它们之间的关系和底层原理,导致现在出现了遇到问题我可以解决,但要问我“为什么这么做”…包括之前去的多益公司的提前批笔试的信息安全工程师,卷子发下来直接蒙了,平时可都是现用现查的好不好…但问题最终都归于自己,抱怨是没用的,小小少年想要改变这个世界就要先适应这个世界,并努力不被这个世界改变,鸡汤就到这里,下面介绍干货——
(其实我就是在各个招聘网站上收集起来的… )

大纲

1.windows、android、ios、mac 的工作原理(我研究的是游戏领域,所以就不说 Linux 啦)
2.网络通信方式和协议(比如游戏前后端的交互是怎样进行的)
3.高级语言
4.汇编、编译原理
5.加壳 / 脱壳
6.逆向工具
7.加密算法
8.软件漏洞
9.游戏引擎 / 开发框架
10.反调试 / 反外挂 / 反虚拟机 / 反修改 / 反加速 / 内存保护

一、windows、android、ios、mac 的工作原理

1.Windows

Windows 基于 “消息” 来设计程序 ,当需要完成某个功能时会调用操作系统的某个支持,操作系统将用户的 “需求” 包装成 “消息” ,加入到消息队列,之后应用程序会从消息队列中取走 “消息” 并作出相应。
以下是操作系统、应用程序、输入输出设备 之间的关系:
③:应用程序的功能都是通过调用函数来实现的,所以应用程序也是以 “函数调用” 的方式通知操作系统要执行某些功能。操作系统把它能完成的功能以 “函数” 的形式提供给应用程序使用,也就是所谓的 “系统调用” (也就是API)。【如:调用声卡发出声音】
④:比如按下 “A” 这个按键,操作系统感知到这个行为,但是操作系统并不对这个行为进行处理,而是把这个 “消息” 传递给应用程序,由应用程序作出相应的反应。

那么操作系统怎么把感知到的事件传递给应用程序的呢?
这是通过 “消息机制”(message)来完成的。操作系统将每个事件写成一个 Struts ,然后把这个 struct 发送给应用程序:

typedef struct tagMSG{HWND hwnd; // 消息所指窗口句柄UINT message; //消息代号(大多以宏的形式存在)WPARAM wParam; //16位系统的产物,为了可移植性而保存了下来。(word)LPARAM lParam; //16位系统的产物,为了可移植性而保存了下来。(long)DWORD time; //消息创建时间POINT pt; //消息创建时的鼠标位置
} MSG;

操作系统为每个应用程序建立一个 “消息队列”(实际上就是一个先进先出的缓冲区,在代码中以数组形式出现) ,由于应用系统有对应的针对某个消息的处理代码,所以就接管了消息并按照自己的意愿去执行接下来的操作,就是所谓的 “消息相应” 。
【例如,当应用程序收到了 WM_CLOSE 消息,就在代码里调用 DestroyWindow 这个 API】
下图是消息队列的工作流程:
“消息循环” 和 “窗体过程” 是紧密相关的,上图中的 “窗体过程” 其实就是一个线程,我们都知道一个进程可以包含多个线程。不过 “窗体” 是一种特殊的线程 —— “UI线程” ,每个"UI线程" 都有一个消息循环队列。
在窗体中点击按钮或其他操作,就会向消息循环队列中插入消息,然后按照程序的逻辑调用系统的函数,再交给用户处理。

Windows 程序入口点
当一个 Windows 程序被打开时,就进入了该程序的 “入口函数” WinMain(类似 Dos 程序的入口点 main):

int APIENTRY _tWinMain(
HINSTANCE hInstance,    // 实例句柄(进程句柄),比如同一个 exe 程序可以被打开多个,为了区分它们就要分配不同的句柄
HINSTANCE hPrevInstrance,   // 上一个进程句柄(设置为 NULL ,代表现在是第一个),可以配合 if(hPrevInstance) return 0;  实现 "游戏客户端只能被打开一个" 的效果
LPSTR lpCmdLine,    // 命令行参数 (比如在 cmd 命令行下输入:XXX.exe 参数)
int nCmdShow,   // 窗口显示状态(最大化、最小化、隐藏)
);

窗口创建过程
1.设计窗口(具体参数的取值,请查阅 MSDN)

typedef struct _WNDCLASS { UINT style;  // 窗口样式WNDPROC lpfnWndProc;     // 窗口回调函数(应用程序收到消息,就通知操作系统调用某个函数来处理它,lpfnWndProc 指定了操作系统调用应用程序的哪个函数)int cbClsExtra;   // 0int cbWndExtra;     // 0HANDLE hInstance;   // 提供回调函数的实例句柄HICON hIcon;  // 窗口图标句柄HCURSOR hCursor;   // 窗口光标句柄HBRUSH hbrBackground;  // 窗口重画刷子句柄LPCTSTR lpszMenuName;    // 菜单LPCTSTR lpszClassName;     // 窗口类名
} WNDCLASS;

回调函数(举例):

typedef int (*PFUN)(int x,int y);int add(int x,int y);
PFUN pfun=add;
int sum=pfun(3,5);

2.注册窗口类

RegisterClass(CONST WNDCLASS *lpWndClass); // 参数为 WNDCLASS 结构体中的 "窗口类名"

3.创建窗口(成功则返回创口句柄,否则返回 NULL)

HWND CreateWindow(LPCTSTR lpClassName, // 窗口类名LPCTSTR lpWindowName, // 窗口标题文字DWORD dwStyle,        // 窗口样式int x,                // 窗口左上角 x 坐标int y,                // 窗口左上角 y 坐标 int nWidth,           // 窗口宽度int nHeight,          // 窗口高度HWND hWndParent,      // 父窗口句柄HMENU hMenu,          // 菜单句柄 / 子窗口句柄HANDLE hInstance,     // 窗口所属应用程序的实例句柄LPVOID lpParam        // 附加信息
);

4.显示窗口

BOOL ShowWindow(HWND hWnd,     // CreateWindows 返回的窗口句柄int nCmdShow   // 窗口显示状态
);BOOL UpdateWindow(HWND hWnd   // handle to window
);

消息循环
上面说到了消息循环是和 “UI线程”(也就是窗体) 紧密相关的 , 窗体使用 GetMessage 从消息队列中取走一条消息:

BOOL GetMessage(LPMSG lpMsg,         // 接收消息代号的指针HWND hWnd,           // 消息来源的窗口句柄UINT wMsgFilterMin, // 接收某一范围之内的消息(开始)UINT wMsgFilterMax   // 接收某一范围之内的消息(截止)
);

回调函数

LRESULT CALLBACK 我们的函数名(HWND hwnd,      // 窗口句柄UINT uMsg,      // 消息代号WPARAM wParam, // 消息参数 1LPARAM lParam   // 消息参数 2
);swtich(uMsg){case 消息代号1:...case 消息代号2:...case 消息代号3:...default:...
}

Windows 内核机制
windows 采用双模式来保护操作系统本身(r0、r3),intel 处理器有 4 个等级(r0-r3),但是 windows 系统只用了其中两个,用户态比较容易理解,下面主要讲 r0 内核态。

每当应用程序需要用到 r0 的功能时,就会从 r3 模式转换为 r0 模式(通过 ntdll.dll 来实现切换,类似的还有异常、中断,都会切换到 r0),之后再切换回来。在 r0 代码可以访问 4 GB 的虚拟内存,而 r3 代码只能访问 2GB 的虚拟内存空间。

另外 r0 区域对于所有的进程来说都是共享的,所以进程执行内核代码实际上就是使用操作系统的 “服务”,Windows 将这些系统服务组成了一张表,也就是 SDT 表(服务描述符表)。

windows 内核结构:1.硬件抽象层:把与硬件相关联的代码隔离到一个专门的模块内。目的是让 Windows 可以被移植到不同的硬件平台上。
2.内核层:包含基本操作系统功能:进程线程的调度、中断和异常处理、同步机制等(位于 ntoskrnl.exe 中)
3.执行体层:提供可以被程序调用的功能(位于 ntoskrnl.exe 中),当然有些函数只能在 r0 中使用,也就是驱动文件才能调用这类方法。
4.内核驱动程序:内核中除了nyoskrnl.exe 和 hal.dll 以外,其他部分基本都以 “驱动程序” 的形式存在(可以理解为 Windows 内核的一种扩展),属于标准 PE 文件。

另外看 Windows\system32 下的几个文件:

hal.dll
WinNT内核(包括 XP)操作系统的核心驱动,“标准个人电脑” 的硬件抽象层实现(Windows 开发目标之一就是要在多种硬件平台上移植)。


ntoskrnl.exe
存放了大量内核二进制代码,用于内核调用,并提供系统的基本机制(线程调度、内存分配等)。


ntdll.dll、kernel32.dll
kernel32.dll 存放了 Win32 API 函数,但不实现详细的功能,仅仅是做了一个地址指针转换,让函数入口点跳到 NTDLL.DLL 里。NTDLL.DLL也不做详细的处理(算是 r3 和 r0 连接的桥梁),通过系统功能调用将用户级的函数调用转换成内核模式的真正的系统功能调用,由内核执行完成后返回应用程序进程。对于内核中的每个服务,ntdll.dll 都提供一个相应的函数(一般以 Nt 开头)。


gdi32.dll、user32.dll
提供了 Win32 图形编程接口,也通过 NTDLL.DLL 完成系统画图功能。


总结:以上文件都是将 Win32 API ,翻译成本机 API 供开发人员调用。


系统进程和系统线程
windows 系统线程运行在 System 这个进程内:
驱动程序可以在 “调用这个驱动的进程” 中创建线程,也可以在这个 System 进程中创建线程(当然也可以不创建线程…)。

然后是系统进程:

进程名 介绍
System Idle Process 不是一个真正的进程,在没有可用的进程时,此时就是此进程在运行
System 包含了内核模式的系统线程(系统辅助线程、执行体/驱动 创建的线程)
smss.exe 第一个被创建的 r3 进程,也叫会话管理器,用来初始化系统环境变量
winlogon.exe 登录进程,ctrl+alt+delete 就调用了这个进程
csrss.exe Windows 子系统进程,提供一个子系统环境(比如命令行)
lsass.exe 负责本地安全策略,例如允许哪些用户登录、系统安全日志等
exporer.exe Shell,提供系统与用户交互的界面(开始菜单、任务栏等)
services.exe 管理 Windows 系统服务(服务可以理解为在 r0 下的进程)

PE 文件结构
参考文章:https://blog.csdn.net/Simon798/article/details/95212515
常见的 PE 文件有 exe、dll、sys等。下面是 PE 文件的结构图:

DOS 头(为了兼容 dos 系统)
_IMAGE_DOS_HEADER
① MZ 头:真正的 dos 头,前两个字节为 MZ。
② dos 存根:用来输出提示字符串。


PE 头(存放文件的信息)
_IMAGE_NT_HEADERS
① PE 标识:就是 _IMAGE_NT_HEADERS 结构体中的 ‘Signature’ 属性
② 文件头:包含了 PE 文件的基础信息。 _IMAGE_FILE_HEADER
③ 可选头:对文件头的补充,管理 PE 文件被操作系统装载时需要的信息。 _IMAGE_OPTIONAL_HEADER


节表(存放可执行文件映射到内存的位置)
_IMAGE_SECTION_HEADER
节表的个数对应 _IMAGE_FILE_HEADER 的 NumberOfSections 属性。


区段(存放节数据的地址范围)
参考:https://blog.csdn.net/Simon798/article/details/96876910


Windows 多线程
参考:https://www.cnblogs.com/bhlsheji/p/4182014.html

首先要了解线程的本质,进程仅仅是线程的容器,一个程序在运行的时候起作用的永远都是线程。如果硬说进程有什么作用,那就是进程可以创建线程并对它分配资源(线程的消亡受自身控制,自己杀死自己),并且线程问共享同一进程下所有的 “内核对象”。

内核对象
C++中 类有类的对象,对象有权限访问类中的方法和属性。同理,Windows也自己的类,但不是公开的。可以通过调用函数创建这些不公开类的对象对Windows进行操作。而产生的对象,就称为内核对象。
内核分配的一个内存块,只能被内核访问,一旦内核对象不再被使用,内核就会释放掉这个内核对象。每一个进程在初始化的时候被分配一个句柄表,存储内核对象的句柄,句柄表的具体结构微软没有发布,大致包括三个内容:内核对象句柄,内核对象地址,訪问屏蔽标志。

在调用 CreateThread 函数后,操作系统生成了一线程内核对象(可以理解为所有的内核对象都与线程有关),然后在进程空间内为这个线程分配资源。

那么为什么要实现多线程? 原因是进程频繁切换的开销会严重影响系统性能,而线程的切换是轻量级的,所以可以保证足够快。并且多线程与 ‘栈’ 关系密切。
参考:https://www.cnblogs.com/yinbiao/p/11177748.html


文件系统过滤驱动
参考:https://wenku.baidu.com/view/45b2bfc3aa00b52acfc7ca84.html

首先要知道什么是 “文件系统驱动” ,其实就是存储设备的驱动(比如 NTFS 类型的硬盘,对应的文件系统驱动就是 ntfs.sys)。它的工作流程如下:
1.用户操作文件(读、写等)
2.内核调用对应的服务向 I/O 管理器发送 I/O 请求
3.I/O 管理器检查访问的数据时候保存在缓存中,有则构造 I/O 请求包从缓存中提取数据,没有则构造普通 I/O 请求包给文件系统驱动(同时将数据装入缓存),文件系统驱动处理完成后将结果返回给应用程序。

而 “文件系统过滤驱动” 就是通过拦截 “I/O 请求包”,符合要求的包继续向下发送,不符合则直接向上返回这样的原理来实现的。


虚拟设备驱动
参考:http://blog.sina.com.cn/s/blog_657f0c830101cgtn.html

系统的实际掌控权并不掌控在 gdi32,kernal32,user32等核心 dll 中,它们都属于 r3 层,真正的 “幕后军师” 其实是 虚拟级管理器(VMM)虚拟设备驱动程序(VxD) (WindowsNT 下不支持,属于 Windows 9x 特有)

背景故事
在Window 3.x的时代,在市场上有很多成功的dos软件。Windows 3.x必须同时运行普通的Windows程序和dos程序,否则,它就会失去市场。解决办法就是把 dos 程序运行在一个虚拟机上,把 windows 程序运行在另一个虚拟机上。这就是 VMM 和 VxD 出现的原因。

VMM 实际上就是一个特殊的 VxD 程序,它被加载到内存,用来监视其他的 VxD 程序。

VxD (‘x’ 不固定,代表设备名),dos 程序认为它拥有一切,当它在虚拟机中运行时,Windows 会给它一个实机器的替身,也就是 VxD。VxD 控制真正的硬件设备并共享给各虚拟机。 当然, VxD 程序也没有必要一定和硬件设备关联(这样就算是 r0 的一刻扩展)。


注册表
参考:https://max.book118.com/html/2015/0923/26056709.shtm

可以吧注册表看成一个 “数据库”,存放了各种配置信息。首先看注册表的根目录:

HKEY_CLASSES_ROOT
(存储Windows可识别的文件类型的详细列表,以及相关联的程序。)HKEY_CURRENT_USER
(存储当前用户设置的信息。)HKEY_LOCAL_MACHINE
(包括安装在计算机上的硬件和软件的信息。)HKEY_USERS
(包含使用计算机的用户的信息。)HKEY_CURRENT_CONFIG
(这个分支包含计算机当前的硬件配置信息。)

一些重要数据在注册表中存放的位置:

名称 注册表分支 作用
SYSTEM HKEY_LOCAL_MACHINE\SYSTEM 存储计算机硬件和系统的信息
NTUSER.DAT HKEY_CURRENT_USER 存储用户参数选择的信息
SAM HKEY_LOCAL_MACHINE\SAM 用户及密码的数据库
SECURITY HKEY_LOCAL_MACHINE\SECURITY 安全性设置信息
SOFTWARE HKEY_LOCAL_MACHINE\SOFTWARE 安装的软件信息
DEFAULT HKEY_USERS\DEFAULT 缺省启动用户的信息
USERDIFF HKEY_USERS 管理员对用户强行进行的设置

2.android
之后补充…3.ios
之后补充…4.mac
之后补充…

二、网络通信方式和协议(比如游戏前后端的交互是怎样进行的)

我们上面介绍了本地之间的进程通信(Windows 的消息机制),但是本地进程通信不止有消息队列一种,还有如下方法(看看就行了,不细说):

1、消息传递(管道、FIFO、消息队列)
2、同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量)
3、共享内存(匿名的和具名的)
4、远程过程调用(Solaris门和Sun RPC)

下面主要讨论 “网络” 中的进程通信。网络之间的进程通信利用 “ip地址,协议,端口” 来作为进程的唯一标识符(类似本地进程通信的 PID),其中 ip 地址就是你设备的 ipv4 , 协议就是 TCP/IP(目前使用 socket 编程接口),端口就是这个进程在本机上申请的端口(一般位数较大)

Socket 中 TCP 的三次握手
1.客户端调用 socket 的 connect 函数

int connect(int sockfd,  // 客户端 socket(也叫 '套接字')const struct sockaddr *addr,   // 服务器 socket 地址socklen_t addrlen   // 服务器 socket 地址长度
);

通过 connect 发出连接请求,向服务器发送了 SYN J 包(SYN表示建立连接),之后connect 进入阻塞状态。

2.服务器收到 SYN J 包,调用 accept 函数接收请求:

int accept(int sockfd,    // 服务器 socketstruct sockaddr *addr, // 客户端协议地址socklen_t *addrlen    // 协议地址长度);

然后向客户端发送 SYN K、ACK J+1(ACK表示响应),之后 accept 进入阻塞状态。

3.客户端收到服务器的SYN K ,ACK J+1,connect 返回,并向服务器发送 ACK K+1。
4.服务器收到ACK K+1时,accept返回。

Socket 中 TCP 的四次挥手
① 客户端主动关闭:
1.应用程序调用 close 函数关闭连接:

int close(int fd); // fd 为 open() 或 creat() 的返回值

并向服务端发送 FIN M(FIN表示关闭连接),之后 close 被挂起

2.服务器接收到FIN M之后,执行被动关闭,并将 ACK M+1 作为文件结束符发送给客户端。
3.客户端接收到文件结束符,调用 close 关闭 socket

② 服务端主动关闭:
(原理类似)

高级语言

C++(方便做较细致的操作,比如操作内存)

ELS:标准模板库,提供了 list,vector,set,map 等容器。
反射:本质就是使用字符串动态创建对象。参考:https://www.jianshu.com/p/8e35080ceb0d
注入:分为 DLL 注入和代码注入。参考:https://blog.csdn.net/qq_33565146/article/details/79273003

C#(方便调用接口)
Lua(游戏领域广泛使用的脚本语言,可用来开发游戏的扩展功能,也就是嵌入到客户端内运行)

之后补充…

汇编、编译原理

x86 汇编
windows 32 位汇编,也是最常见的汇编。

x64 汇编
windows 64 位汇编。与 32 位汇编的区别如下:

32位汇编 64位汇编
寄存器 8个 16个
参数的保存位置 栈帧 寄存器:rdi,rsi,rdx,rcx,r8,r9作为第1-6个参数。rax作为返回值
栈帧 ebp作为栈帧指针 无(使用通用寄存器替代)

ARM 汇编
一种处理器架构,特点是续航时间长,但性能比 x86/x64 差,广泛应用在移动设备上。学习 ARM 汇编主要是为了分析 .so 文件(Linux 下的动态链接库,因为 Android 基于 Linux 的内核。.so 文件用 c 编写)

smali 汇编
基于 Android 的 Dalvik 虚拟机的汇编语言,学习 smali 主要是为了分析 .dex 文件(由 .jar 文件经过编译得到),但是大多数 java 项目都可以反编译成源码,所以相对于 ARM 汇编来说,smali 汇编显得不那么重要了。

编译原理
参考:https://blog.csdn.net/lovesummerforever/column/info/bianyiyuanli

加壳脱壳

首先要知道,什么是壳?
加壳就是一种特殊的算法,对EXE、DLL文件进行压缩(类似WINRAR,区别是这个压缩的程序可以独立运行),解压过程完全隐蔽。

壳运作的原理
加壳工具在文件头里加了一段指令,告诉CPU,怎么才能解压自己。现在的CPU都很快,所以这个解压过程你看不出差别(加“壳”虽然增加了CPU负担,但是减少了硬盘读写时间,实际上运行速度更快)。在打开程序的时候,“壳” 会比程序优先运行并得到对程序的控制权,对原始程序进行解密、还原,还原完成后再把控制权交还给原始程序,执行原来的代码部分。加壳后,程序在磁盘中以加密的形式存在,只在执行时在内存中还原,从而防止程序被静态反编译。

壳的分类
1.压缩壳
2.加密壳
3.伪装壳
4.多层壳

听起来很牛逼,难道没有办法了么 ?
当然有办法 ——
(要不然还特么要我们干什么…)

脱壳
首先要明白加壳的目的,是为了隐藏程序的入口点(OEP),一般的脱壳思路如下:
查壳->寻找OEP->Dump->修复
查到壳的类型,先找对应壳的全自动脱壳机,如果走运就可以直接到OEP,但大多数情况下也要手动脱壳,用到的工具:TRW2000、TR、SOFTICE等。每种壳的脱发不同,需要具体情况具体分析,这里不一一介绍。

逆向工具

OllyDbg动态调试工具

IDA静态分析工具

C32ASM静态分析工具(相比 IDA ,可以显示 16 进制数据)

WinDbg内核调试工具

Softice内核调试工具

JD-GUIjava 反编译工具

GDBLinux 下的调试工具

之后介绍…

加密算法

MD5
将明文加密成 32 个 16 进制字符组成的字符串。完全相同的一段数据,不论时间地点,加密出的32位的字符串完全相同。算法本身不可逆,但是可以用穷举的方式暴力破解(md5 解密网站都是用的这个原理)。

BASE64
加密长度不定长,由 数字+大小写字母+特殊字符 构成。算法本身可逆 !

SHA1
类似 MD5(都由 MD4 导出)算法本身不可逆 ,区别是加密过的密文位 40 位,所以安全性比 MD5 更高。但速度比 MD5 慢。

HMAC_SHA1
相对于 SHA1, HMAC_SHA1 也是 40 位,但需要一个密码,根据密码的不同,密文的结果也不同。算法本身不可逆。

AES
(对称机密)需要密码,加密长度不定长,由 数字+大小写字母+特殊字符 构成。算法本身不可逆。

DES
(对称机密)需要密码,加密长度不定长,由 数字+大小写字母+特殊字符 构成。相对于 AES,DES 的加密速度更快,但是安全性较低。算法本身不可逆。

RSA
(非对称加密)加密长度不定长,由 数字+大小写字母+特殊字符 构成。速度慢,适合对少量数据进行加密。算法本身不可逆。

ECC
(非对称加密),类似于 RSA , 但相比 RSA 由绝对优势(更安全、资源消耗少、加密速度快)。算法本身不可逆。

软件漏洞

参考:https://www.cnblogs.com/linuxsec/articles/10926132.html

游戏引擎 / 开发框架

参考:https://www.ali213.net/news/html/2014-8/112765.html
(对应的实现原理自行搜索)

反调试 / 反外挂 / 反虚拟机 / 反修改 / 反加速 / 内存保护

反调试

参考https://www.jianshu.com/p/0f6e796e813fhttps://bbs.pediy.com/thread-225740.htmhttps://blog.csdn.net/wxh0000mm/article/details/86062361https://www.cnblogs.com/Lthis/p/4207588.html


反外挂
外挂无法被根治的原因:https://baijiahao.baidu.com/s?id=1591845945896734098&wfr=spider&for=pc
反外挂原理:https://www.cnblogs.com/lancidie/archive/2011/12/09/2282785.html


反虚拟机

参考http://xueshu.baidu.com/usercenter/paper/show?paperid=b714285cbab151df87641a183cfe90fc&site=xueshu_sehttps://blog.csdn.net/BeyondCy1993/article/details/77677137https://bbs.pediy.com/thread-225735.htm


逆向工程师要学什么?相关推荐

  1. 写在过年之前:我做逆向工程师的这半年

    去年七月,博主拉着行李来到帝都开始了北漂生活. 初入社会,第一次面试就显地极为老实磕巴紧紧张张.看着面试试题上熟悉而又陌生,疏远而又亲近的知识点,我愣是没有写出一个一二来.内心徘徊了十几分钟,还是喊面 ...

  2. 电子工程师要学的课程有哪些?

    我先晒一下我大学到工作学的课程晒一下吧: 高数.线代.概率论必学(线代用于通信和仿真,概率论用于控制分析,高数就不多说了基础必备): 数电.模电和电路原理(电子三件套,必学): 自控.现控.过控和智控 ...

  3. 二进制逆向工程师_利用Ghidra逆向分析Go二进制程序(下篇)

    (接上文) 动态分配字符串结构 在第一种情况下,字符串结构是在运行时创建的,为此,需要使用一系列汇编指令在字符串操作之前设置相应的结构.由于指令集的不同,不同的架构之间的结构也是不同的.让我们通过几个 ...

  4. 网路工程师要不要学mysql_网络工程师要学什么_网络工程师需要的技能

    如果以后想从事网络工程师这个岗位,同学们知道 网络工程师要学什么 吗?本期乔布 网络工程师需要的技能 . 关键词: 网络工程师要学什么 , 网络工程师需要的技能 网络 基础知识:深度网络基本概念,例如 ...

  5. 新职业人工智能工程师要学哪些内容?

    新职业人工智能工程师要学哪些内容? [导语]人工智能专业学习课程包括认知心理学.神经科学基础.人类的记忆与学习.语言与思维.计算神经工程.人工智能平台与工具.人工智能核心等,应该掌握好这些理论知识才能 ...

  6. UC-Android逆向工程师面试第2题分析

    博客链接:http://blog.csdn.net/qq1084283172/article/details/52133172 一.简介 这个题目是别人面试UC优视集团Android逆向工程师一职位的 ...

  7. 游戏安全逆向工程师:从入门到精通83课分享

    游戏安全逆向工程师-01.简单的介绍一下DLL是怎样的一种存在 游戏安全逆向工程师-02.Windows.API编程速成-环境搭建 游戏安全逆向工程师-03.Windows_API是什么东西 游戏安全 ...

  8. 视频教程-Java工程师必学系列课程之4--《Java Swing》视频课程-Java

    Java工程师必学系列课程之4--<Java Swing>视频课程 某知名科技公司技术总监,10年以上大型J2EE项目的实战研发经验,参与并主持开发"内蒙古电力集团考试系统&qu ...

  9. 量化系统工程师需要学什么?

    量化系统工程师需要学什么? 原创: 陈益波 FICC与资产配置 昨天 题记:作者2015年博士毕业加入一家量化私募公司,已经做了差不多四年系统工程师的工作.本文是根据这个岗位所用到的日常工作技能总结, ...

最新文章

  1. Java实现单链表、栈、队列三种数据结构
  2. python 只执行一次_Python 定时任务实现只执行一次的方法
  3. pytest_01-环境准备与入门
  4. excel图表之道_学习笔记:Excel之图表布局
  5. c 命令导出数据到mysql_MySQL命令行导出数据库
  6. centos7 geenplum5.x postgis开源版本编译
  7. 继承情况下构造方法的调用过程-java
  8. CocosCreator2.3.1按钮节点防止多次连续点击
  9. 如何为 Mac 添加新语言?
  10. 京瓷m1025维修模式进不去_多个品牌复印机进入维修模式步骤大全
  11. eclipse换炫酷主题
  12. 第三部份:glibc升级到glibc-2.30
  13. Android实现截屏功能(已适配Android11)
  14. 领域迁移机器翻译方案总结
  15. EffectCreator for mac(抖音短视频编辑软件)
  16. idea为什么不显示运行按钮_idea 右键项目没有run 运行选项
  17. 移动端天气系统--【下雨】效果之【雨滴】的实现和分析
  18. 129、易燃气体的分级
  19. APS54085 线性PWM调光降压 LED恒流驱动芯片
  20. 2014522420145238《信息安全系统设计基础》实验一 开发环境的熟悉

热门文章

  1. iphoneX面部识别带来的隐私问题
  2. 整合定位技术应对物联网碎片化场景应用
  3. HCIP-第十二天-MPLS+VNP
  4. 张一鸣, 9 年前重点在做这两件事
  5. latex学习笔记-参考文献上标与非上标混合使用
  6. hdoj_1196_Lowest Bit 树状数组基本思想
  7. excel格式调整:表格应用中格式刷技法汇总
  8. 单链表实现增删改查(进化版)
  9. 贪婪模式和非贪婪模式
  10. C语言字符型PPT,C语言字符串ppt课件