今天整理硬盘突然看到几年前做PC病毒分析师时整理的自己一些面试题和一些网上收集的面试题,还有一些可能有用的东西。放上来希望能给对病毒分析感兴趣和或者希望从事这个行业的同学一些帮助和指导。(其中的一些面试题例子我是用加密解密这本书中的例子做的解答)
*******************************************************************************
InLine HOOK中_declspec(naked) 使用
对于jmp类型的hook, 如果自己的过程没有使用_declspec(naked),那么系统会自动给添加一些额外的代码,控制堆栈平衡,但是这些额外的代码会破坏被hook函数的堆栈。
对于call类型的hook,如果使用_declspec(naked)修饰的话,要注意自己恢复堆栈平衡。
下面是网上对_declspec(naked) 的介绍:
_declspec(naked)
就是告诉编译器,在编译的时候,不要优化代码,通俗的说就是
没代码,完全要自己写
比如
#define NAKED __declspec(naked)
void NAKED code(void)
{
__asm
{
ret
}
}
使用__declspec(naked)关键字定义函数:
1,使用 naked 关键字必须自己构建 EBP 指针 (如果用到了的话);
2,必须自己使用 RET 或 RET n 指令返回 (除非你不返回);
_delcspec(naked)用在驱动编写,C语言内嵌汇编完成一些特定功能。
*******************************************************************************
反虚拟机检测
一般程序中检测虚拟机是通过检测虚拟机的后门(VMwar系统存在后门,用于虚拟系统和真实系统的交互)来判断是否程序运行在虚拟机中。检测虚拟机的代码:
bool IsInsideVMWare()
{
bool rc = true;
__try
{
__asm
{
push edx
push ecx
push ebx
mov eax, 'VMXh'
mov ebx, 0 // any value but not the MAGIC VALUE
mov ecx, 10 // get VMWare version
mov edx, 'VX' // port number
in eax, dx // read port
// on return EAX returns the VERSION
cmp ebx, 'VMXh' // is it a reply from VMWare?
setz [rc] // set return value
pop ebx
pop ecx
pop edx
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
rc = false;
}
return rc;
}
eax里面放着‘VMXh’那就是虚拟机了,注意字符串的顺序,‘V’是高位,‘h’是低位,其他字符串也是这样。
第一步要做的就是定位关键代码,我选择定位字符串‘VMXh’,搜索‘hXMV'的ASCII码(注意高位低位!)
004013C6 . 52 push edx
004013C7 . 51 push ecx
004013C8 . 53 push ebx
004013C9 . B8 68584D56 mov eax,0x564D5868
004013CE . BB 00000000 mov ebx,0x0
004013D3 . B9 0A000000 mov ecx,0xA
004013D8 . BA 58560000 mov edx,0x5658
004013DD . ED in eax,dx
004013DE . 81FB 68584D56 cmp ebx,0x564D5868
004013E4 . 0F9445 E4 sete byte ptr ss:[ebp-0x1C]
004013E8 . 5B pop ebx
004013E9 . 59 pop ecx
004013EA . 5A pop edx
004013EB . EB 0B jmp Xalg1.004013F8
004013ED . 6A 01 push 0x1
004013EF . 58 pop eax
004013F0 . C3 retn
004013F1 . 8B65 E8 mov esp,dword ptr ss:[ebp-0x18]
004013F4 . 8365 E4 00 and dword ptr ss:[ebp-0x1C],0x0
004013F8 > 834D FC FF or dword ptr ss:[ebp-0x4],0xFFFFFFFF
004013FC . 8B45 E4 mov eax,dword ptr ss:[ebp-0x1C]
004013FF . 8B4D F0 mov ecx,dword ptr ss:[ebp-0x10]
00401402 . 64:890D 00000>mov dword ptr fs:[0],ecx
00401409 . 5F pop edi
0040140A . 5E pop esi
0040140B . 5B pop ebx
0040140C . C9 leave
0040140D . C3 retn
……
0040137F . C9 leave
00401380 . C3 retn
00401381 /$ E8 0F000000 call alg1.00401395
00401386 |. 85C0 test eax,eax //返回的关键值 根据返回值判断
00401388 |. 75 07 je Xalg1.00401391 更改指令为jne 401391 或者其它跳转指令即可越过虚拟机检测
0040138A |. 6A 00 push 0x0
0040138C |. E8 8B410000 call alg1.0040551C
00401391 |> 6A 01 push 0x1
00401393 |. 58 pop eax
00401394 \. C3 retn
00401395 $ 55 push ebp
在它传回返回值时修改跳转指令即可越过虚拟机检测
怎么定位导入函数的地址
PE头位置 + 78H 得到IMAGE_DATA_DIRECTORY(数据目录表)的位置,
(也可直接PE头位置+80H 直接得到Import Table 的位置)
IMAGE_DATA_DIRECOTRY STRUC
VirtualAddress DWORD ? ;数据块起始地址
Size DWORD ? ;数据块的长度
IMAGE_DATA_DIRECOTRY ENDS
假设PE文件头的起始地址为B0h,则输入表地址为B0h + 80h = 130h,在130h处发现四字节指针40 20 00 00,倒过来为2040即输入表在内存中偏移量。
IMAGE_DATA_DIRECTORY第二个元素为Import Table,输入表以一个IMAGE_IMPORT_DESCRIPTOR(简称IID)数组开始。
假设2040位于.rdata块中,其虚拟偏移为2000h,物理偏移为600h,因此k=2000h-600h = 1A00h.相对虚拟地址2040h转化为物理地址2040-1A00h = 640h。640h处为IMAGE_IMPORT_DESCRIPTOR。
IMAGE_IMPORT_DESCRIPTOR STRUC
union
Characteristics DWORD
OriginalFirstThunk DWORD ?指向输入名称表(简称INT)
ends
TimeDateStamp DWORD ?时间标志 可以忽略
ForwarderChain DWORD ?第一个被转向的API索引,一般为0
Name DWORD ?DLL名字的指针
FirstThunk DWORD ?指向输入地址表(简称IAT)
IMAGE_IMPORT_DESCRIPTOR ENDS
FirstThunk和OriginalFirstThunk非常类似,指向相同的数组IMAGE_THUNK_DATA结构数组。
假设Name的值为7421 0000 倒过来为虚拟偏移地址2174h,物理便宜地址2174h-1A00h = 774h,查看文件中774h的字符就是调用的DLL名字
OriginalFirstThunk处的值为8C20 0000,倒过来为208Ch,物理地址为208Ch-1A00h = 68Ch,
68Ch处就是IMAGE_THUNK_DATA数组。
IMAGE_THUNK_DATA STRUC
union u1
ForwarderString DWORD ?指向一个转向者字符串的RVA
Function DWORD ?被输入的函数的内存地址
Ordinal DWORD ?被输入的API的序数值
AddressOfData DWORD ?指向IMAGE_IMPORT_BY_NAME
ends
IMAGE_THUNK_DATA ENDS
IMAGE_IMPORT_BY_NAME STRUC
Hint WORD ?
Name BYTE ?
IMAGE_IMPORT_BY_NAME ENDS
假设的其中一个IMAGE_THUNK_DATA值是1021 0000 倒过来即为虚拟偏移地址2110h,物理偏移地址2110h – 1A00h = 710h,偏转到710处位置就会看到函数名字字符串。
注入方式 怎么实现
反调试技术 反虚拟机检测 花指令解决办法 IDC脚本 网络数据分析 调试方法
*******************************************************************************
汇编知识
Mov dl,0dh 回车控制字符0Dh
Mov dl,0ad 换行控制字符0Ah
Mov al,[bx]
or al,al 判断选取的字符是否为零
jz done
or al,20h 转化小写字母为大写字母(使用D5=1)
串操作指令LODSB/LODSW是块装入指令,其具体操作是把SI指向的存储单元读入累加器,其中LODSB是读入AL,LODSW是读入AX中,然后SI自动增加或减小1或2位.当方向标志位D=0时,则SI自动增加;D=1时,SI自动减小。
test eax, eax
je 00401083
test指令操作是目的操作数和源操作数按位逻辑“与“运算,结果不送回目的操作数然后根据结果设置SF、ZF、和PF标志位,并将CF和OF标志位清零。而JE是当ZF=1时跳转。
即,当eax的值等于0时跳转。因此说,这里的test就是检测eax的值是不是0
mov eax,0a
text eax,eax
je xxxx,这个跳会跳吗?能详细解释下test eax,eax这是什么意思?
test eax,eax 基本上和 And eax,eax 是一样的,不同的是test 不改变eax的结果,只是改变FLAG寄存器的状态,也就是改变进位标志,零标志,溢出标志等。
举一个例子,如果eax=01h,test eax,eax 就是两个01h 作与操作,所以结果还是01h,不是0的话,就不会跳转 je xxxx。所以要跳转je xxxx,只有一种可能就是eax=0h.所以现在eax=0a 则不会跳转 je xxxx
push offset LibFileName ; "Raining.dll"
call ds:LoadLibraryA ; 加载Raining.dll
test eax, eax ; 检测Raining.dll是否加载成功
jnz short loc_401012
*******************************************************************************
mov ax,5
lea ax,[ax+6]
此时ax=11.象这种情况,lea基本上可以看成相加,但要比add速度快
lea实现的是把内存地址赋予寄存器
如MOV AX,OFFSET BUF和LEA AX,BUF
实现的功能都一样,都是把BUF的首地址赋给AX寄存器
怎么进行远程线程注入?
SSDT Hook
调用约定
C的调用方式_cdecl(参数从右向左依次入栈) 清理方式:调用者清理
对于参数可变化的:printf("XXXXX");
void demo_cdecl(int w,int x, int y, int z)
asm:
push z
push y
push x
push w
call demo(进入了函数,开始执行了。。。。。。)
add esp, 16 4*sizeof(int)
标准调用_stdcall
void demo_stdcall(int w,int x, int y, int z)
asm:
push z
push y
push x
push w
call demo(进入了函数,开始执行了。。。。。。)
ret 16
快速调用_fastcall 前两个参数将被分配给ECX,EDX 其它按着_stdcall调用方式 ret 8
C++调用约定 使用this指针
VC提供了 thiscall调用, 将this 传递给ecx
gc++中被当做静态变量,存放在栈顶 题目1:写出DLL劫持原理,并写出哪些DLL 不能被劫持
Windows操作系统在加载PE文件的时候通过输入表会优先加载程序目录下的DLL,而之后才再系统目录中寻找。伪造的dll制作好后,放到程序当前目录下,这样当原程序调用原函数时就调用了伪造的dll的同名函数,进入劫持DLL的代码,处理完毕后,再调用原DLL此函数。
此种方法只对除kernel32.dll、ntdll.dll等核心系统库以外的DLL有效,如网络应用程序的ws2_32.dll、游戏程序中的d3d8.dll,还有大部分应用程序都调用的lpk.dll、sxs.dll,这些DLL都可被劫持。
题目2:内核模式下,允许用什么工具进行调试
SoftICE WinDBG(本质是KD) 还有国产的Syserdebugger
题目3:写出实模式下寻址方式
立即数寻址方式
寄存器寻址方式
存储器寻址方式
题目4:概括讲解下游戏木马与下载器的特征。
题目5:GDT 和LDT 分别表示什么
Global Descriptor Table全局描述符表
Local Descriptor Table本地描述符列表
顺便写下
IDT : Interrupt Descriptor Table中断描述符表
题目6:详细讲解SSDT与hook SSDT的区别
通过ring3与ring0直接的win API 联系起来的一个函数服务描述表
例:调用Createthread -> 最后是调用 ntCreatethread 来达到创建线程的目的
那么hook ssdt 就是通过ring0下系统钩子的形式在SSDT 函数服务描述表建立拦截函数调用以及创建的一个监视过程
进ring0的方法太多,比如常规的中断门,陷阱门,调用门等!
这个里面还牵涉内存映射,全局变量共享等概念
简单的来说,SSDT 是 正常行为
HOOK SSDT 是WS行为。
SetwindowshookEx -> CallNextHookEx
题目7:HOOK API 与API HOOK 跟什么有关系?
题目8:特征码分为几种,特征跟病毒是什么关系?
特征码分为两种,内存特征,文件特征
1:内存特征:表示在内存中存在病毒的宿主程序,称代码式注入或DLL注入
2:文件特征:通过读取某个文件PE信息,或者文件偏移量,取出长达26个十六进制字符存入病毒库
现在杀软用的都是Debug 机制,简称:虚拟机查杀
特征就是证明这个是不是病毒,如果是病毒该如何处理。
题目9:Hook OpenProcess 会导致什么,冰刃下SSDT红色部分表示什么?
题目10:主动防御的包括哪些?
HOOK HOOK 再 HOOK 各种病毒行为呗 不知道有什么好问的...
改注册表拉,PE感染拉,SYS感染拉 ShellCode识别拉...
怎么对一个样本进行详细分析,是否进行过详细分析
怎么提取的特征码
分析过哪个病毒
1.如何快速判断一个文件是病毒?
2.病毒和木马有何区别?
3.如何判断一个文件是可执行文件?
答:在IMAGE_DOS_HEADER结构中找出e_lfanew字段的值,然后用该值加上文件基地址以得到的地址为内存地址查看该地址处的值是否为00004550,也就是ASCII码的“PE00”。
4.jmp和call的区别是什么?
答:jmp直接跳转到目标地址,而call先将下一条指令的地址压栈,然后再跳转到目标地址。call指令相当于push + jmp。
7.什么是shellcode?原理是什么?
Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限。另外,Shellcode一般是作为数据发送给受攻击服务的。
8.jmp的机器码是多少?
答:jmp的机器码是EB、E9、EA、FF。
9.pe文件结构大体是什么?
DOS首部
IMAGE_DOS_HEADER
PE文件头
IMAGE_NT_HEADERS
IMAGE_FILE_HEADER
IMAGE_OPTIONAL_HEADER32
块表(Section Table)
IMAGE_SECTION_HEADER
……
块(Section)
.text
.data
……
调试信息
……
10.怎样判断一个文件是exe还是dll?
IMAGE_FILE_HEADER 中的文件属性字段中 普通的EXE文件这个字段值一般是010fh,DLL文件这个字段的值是0210h
11.什么是壳?
12.木马分为哪几类?
13.call A
A:pop eax
指令是什么意思 调用 pop eax 语句
1、_STDCALL的参数压栈方式,堆栈平衡方式
这个比较基础,是从右到左依次压入,CALL内平衡
2、C语言里wsprintf参数的压栈方式,为什么
这个也比较基础,就是从右到左依次压入,CALL外平衡。为什么,,是因为wsprintf的参数是可变的。
3、PE里面物理和文件地址的转换
这个也比较基址,我自觉得对PE还算了解,还算熟悉,所以关于va,rva等这个没有问题。
4、常见的注入方式
Windows Hook、远程线程注入DLL、远程线程注入代码
7、如何分析一个数据的方法:
我答:通过输出字符串,导出函数或者CE工具,定位内存地址,通过IDA静态分析结合 OD动态调试,很快就可以找到想要的了。
问:病毒的行为一般都有哪些
答:打开文件,创建进程,注册表操作,检查有没可移动磁盘的启动。。。。。
问:你有了解过和分析过最近流行的病毒吗?
答:没有,了解过,没分析过
答:U盘自启动
问:一般的感染病毒你了解过吗
答:了解过,添加区段,修改区段大小等等
问:要是添加区段后不能运行怎么办啊
答:要修复那些PE结构相关的成员啊
问:你有分析过盗号的核心技术吗和写过盗号程序吗
答:没有自己的了解过这种技术
问:你一般分析病毒的流程是什么
答:打开虚拟机,拖入IDA,开打监视工具,和XueTr这种类似的工具以便查看释放出来的文件
问:病毒常用的API有哪些?
答:打开文件,打开进程,注册表操作。。。。
结病毒分析师需要的技能如下:
1、至少要了解病毒的行为一般都有哪些
2、病毒行为的详细过程要知道
3、一些简单的工具的开发至少要会
4、分析工具的使用至少要会
5、至少要能写一些辅助病毒分析的工具
作为一个病毒分析师需要的是了解病毒的种类,以及他们的行为特征,还需要了解他们变异后的特点,还要了解病毒常用的API,以及各类病毒专用的API,比如纯Ring3的病毒和加载驱动的病毒,它们的不同之处是加载驱动的病毒里面有着特定的行为,使用了一些专门的API,以及注册表操作等等,对于一个病毒分析师,我们需要精确的定位是不是病毒,或者是不是盗号木马,不能单靠API来判定是否为病毒,比如一个程序里面是正常使用OpenFile,但是你一看见使用了这个API,就把它定义为病毒就错误了,对于这种,我们需要写一些工具来判定它的行为特征,比如HOOK病毒调用的API,我们创建一个挂起进程的病毒,我们这时创建远程线程HOOK掉相关的API,把病毒使用的相对危险的API的参数全部记录下来,这样我们就能快速判断一般的普通病毒了,对于那些猛一点的病毒,或者破坏系统的病毒,这时我们就需要在安全的环境下分析病毒了,以免病毒破坏我们的病毒分析环境,比如你在真实机器上分析一些盗号木马,或者盗取银行账号的木马,那就比较危险了,一般我认为的病毒分析的环境是,如果是感染的病毒,我们需要开着还原系统,还原各个磁盘,一般分析比较危险的病毒这样应该足够了,对于那些破坏还原的病毒,我相信一般的病毒分析是不能分析的!
我们还需要了解和使用常用的病毒分析工具,比如反汇编工具,和动态调试器,各种监视器,以及反Rootkit工具,一般的分析流程总结如下:
1、保护自身机器的安全,也就是还原保护
2、监视器开着,
3、反汇编工具,动态调试器
4、自己的病毒分析辅助工具
5、总结病毒的类型
6、总结病毒的行为和危害
就是需要掌握的技能了,下面的还有一些基本的技能。
我们需要写一些辅助工具来帮助我们辅助分析病毒,下面的是Ring3的说明,当然你也可以写Ring0的工具。
1、注册表监视器,一些病毒经常注册表来对抗一些杀软或者保护自身,比如映像劫持,还有,我前面发过的注册表控制360的开关。
2、文件监视器,一些病毒比如键盘记录这种储存量比较大的东西,就要写入文件了,以及创建文件等等,
3、线程监视器,我们需要监视远程线程的创建,何时创建,何时停止,还是不停止
4、进程监视器,一些病毒经常创建进程来加载一些DLL,以及启动人家的进程。
5、网络监视器,病毒必备的工具,病毒一般得到自己需要的东西后,就发送到自己的机器上,这时我们可以写一些监视工具来辅助抓包分析,抓到的数据包分析等等,以及得到目标的IP地址,好报案等等。 常用的Win API函数(在这里给出做木马病毒常用到的API)
1、限制程序功能函数
EnableMenuItem 允许、禁止或变灰指定的菜单条目
EnableWindow 允许或禁止鼠标和键盘控制指定窗口和条目(禁止时菜单变灰)
2、对话框函数
CreateDialog 从资源模板建立一非模态对话窗
CreateDialogParam 从资源模板建立一非模态对话窗
CreateDialogIndirect 从内存模板建立一非模态对话窗
CreateDialogIndirectParam 从内存模板建立一非模态对话窗
DialogBox 从资源模板建立一模态对话窗
DialogBoxParam 从资源模板建立一模态对话窗
DialogBoxIndirect 从内存模板建立一模态对话窗
DialogBoxIndirectParam 从内存模板建立一模态对话窗
EndDialog 结束一模态对话窗
MessageBox 显示一信息对话框
MessageBoxEx 显示一信息对话框
MessageBoxIndirect 显示一定制信息对话框
GetDlgItemInt 得指定输入框整数值
GetDlgItemText 得指定输入框输入字符串
GetDlgItemTextA 得指定输入框输入字符串
Hmemcpy 内存复制 (非应用程序直接调用)
3、磁盘处理函数
GetDiskFreeSpaceA 获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量
GetDiskFreeSpaceExA 获取与一个磁盘的组织以及剩余空间容量有关的信息
GetDriveTypeA 判断一个磁盘驱动器的类型
GetLogicalDrives 判断系统中存在哪些逻辑驱动器字母
GetFullPathNameA 获取指定文件的详细路径
GetVolumeInformationA 获取与一个磁盘卷有关的信息
GetWindowsDirectoryA 获取Windows目录的完整路径名
GetSystemDirectoryA 取得Windows系统目录(即System目录)的完整路径名
4、文件处理函数
CreateFileA 打开和创建文件、管道、邮槽、通信服务、设备以及控制台
OpenFile 这个函数能执行大量不同的文件操作
ReadFile 从文件中读出数据
ReadFileEx 与ReadFile相似,只是它只能用于异步读操作,并包含了一个完整的回调
WriteFile 将数据写入一个文件
WriteFileEx 与WriteFile类似,只是它只能用于异步写操作,并包括了一个完整的回调
SetFilePointer 在一个文件中设置当前的读写位置
SetEndOfFile 针对一个打开的文件,将当前文件位置设为文件末尾
CloseHandle 关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等
_lcreat 创建一个文件
_lopen 以二进制模式打开指定的文件
_lread 将文件中的数据读入内存缓冲区
_lwrite 将数据从内存缓冲区写入一个文件
_llseek 设置文件中进行读写的当前位置
_lclose 关闭指定的文件
_hread 将文件中的数据读入内存缓冲区
_hwrite 将数据从内存缓冲区写入一个文件
OpenFileMappingA 打开一个现成的文件映射对象
CreateFileMappingA 创建一个新的文件映射对象
MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间
MapViewOfFileEx (内容同上)
CreateDirectoryA 创建一个新目录
CreateDirectoryExA 创建一个新目录
RemoveDirectoryA 删除指定目录
SetCurrentDirectoryA 设置当前目录
MoveFileA 移动文件
DeleteFileA 删除指定文件
CopyFileA 复制文件
CompareFileTime 对比两个文件的时间
SetFileAttributesA 设置文件属性
SetFileTime 设置文件的创建、访问及上次修改时间
FindFirstFileA 根据文件名查找文件
FindNextFileA 根据调用FindFirstFile函数时指定的一个文件名查找下一个文件
FindClose 关闭由FindFirstFile函数创建的一个搜索句柄
SearchPathA 查找指定文件
GetBinaryTypeA 判断文件是否可以执行
GetFileAttributesA 判断指定文件的属性
GetFileSize 判断文件长度
GetFileTime 取得指定文件的时间信息
GetFileType 在给出文件句柄的前提下,判断文件类型
5、注册表处理函数
RegOpenKeyA 打开一个现有的注册表项
RegOpenKeyExA 打开一个现有的注册表项
RegCreateKeyA 在指定的项下创建或打开一个项
RegCreateKeyExA 在指定项下创建新项的更复杂的方式
RegDeleteKeyA 删除现有项下方一个指定的子项
RegDeleteValueA 删除指定项下方的一个值
RegQueryValueA 获取一个项的设置值
RegQueryValueExA 获取一个项的设置值
RegSetValueA 设置指定项或子项的值
RegSetValueExA 设置指定项的值
RegCloseKey 关闭系统注册表中的一个项(或键)
6、时间处理函数
CompareFileTime 比较两文件时间
GetFileTime 得文件建立,最后访问,修改时间
GetLocalTime 得当前本地时间
GetSystemTime 得当前系统时间
GetTickCount 得windows启动至现时毫秒
SetFileTime 设置文件时间
SetLocalTime 设置本地时间
SetSystemTime 设置系统时间
7、进程函数
CreateProcessA 创建一个新进程
ExitProcess 以干净的方式关闭一个进程
FindExecutableA 查找与一个指定文件关联在一起的程序的文件名
FreeLibray 释放指定的动态链库
GetCurrentProcess 获取当前进程的一个伪句柄
GetCurrentProcessId 获取当前进程一个唯一的标识符
GetCurrentThread 获取当前线程的一个伪句柄
GetExitCodeProces 获取一个已结束进程的退出代码
GetExitCodeThread 获取一个已结束线程的退出代码
GetModuleHandleA 获取一个应用程序或动态链接库的模块句柄
GetPriorityClassA 获取特定进程的优先级别
LoadLibraryA 载入指定的动态链接库,并将它映射到当前进程使用的地址空间
LoadLibraryExA 装载指定的动态链接库,并为当前进程把它映射到地址空间
LoadModule 载入一个windows应用程序,并在指定的环境中运行
TerminateProcess 结束一个进程 1.通过FindWindow读取窗体的句柄
2.通过GetWindowThreadProcessId读取查找窗体句柄进程的PID值
var
nProcId:DWord;
nProcId:=GetWindowThreadProcessId(hFound, @nProcId);
3.用OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, ProcessId)打开查到PID值的进程. 此打开具备读取,写入,查询的权限
4.ReadProcessMemory读出指定的内存地址数据
BOOL ReadProcessMemory(
HANDLE hProcess, // 被读取进程的句柄;
LPCVOID lpBaseAddress, // 读的起始地址;
LPVOID lpBuffer, // 存放读取数据缓冲区;
DWORD nSize, // 一次读取的字节数;
LPDWORD lpNumberOfBytesRead // 实际读取的字节数;
); wireshark过滤表达式实例介绍~~
----------------------------------------------------------------------------------------
1、wireshark基本的语法字符
\d 0-9的数字
\D \d的补集(以所以字符为全集,下同),即所有非数字的字符
\w 单词字符,指大小写字母、0-9的数字、下划线
\W \w的补集
\s 空白字符,包括换行符\n、回车符\r、制表符\t、垂直制表符\v、换页符\f
\S \s的补集
. 除换行符\n外的任意字符。 在Perl中,“.”可以匹配新行符的模式被称作“单行模式”
.* 匹配任意文本,不包括回车(\n)? 。 而,[0x00-0xff]* 匹配任意文本,包括\n
[…] 匹配[]内所列出的所有字符
[^…] 匹配非[]内所列出的字符
----------------------------------------------------------------------------------------
2、定位字符 所代表的是一个虚的字符,它代表一个位置,你也可以直观地认为“定位字符”所代表的是某个字符与字符间的那个微小间隙。
^ 表示其后的字符必须位于字符串的开始处
$ 表示其前面的字符必须位于字符串的结束处
\b 匹配一个单词的边界
\B 匹配一个非单词的边界
----------------------------------------------------------------------------------------
3、重复描述字符
{n} 匹配前面的字符n次
{n,} 匹配前面的字符n次或多于n次
{n,m} 匹配前面的字符n到m次
? 匹配前面的字符0或1次
+ 匹配前面的字符1次或多于1次
* 匹配前面的字符0次或式于0次
----------------------------------------------------------------------------------------
4、and or 匹配
and 符号 并
or 符号 或
例如:
tcp and tcp.port==80
tcp or udp
----------------------------------------------------------------------------------------
5、wireshark过滤匹配表达式实例
5.1、搜索按条件过滤udp的数据段payload(数字8是表示udp头部有8个字节,数据部分从第9个字节开始udp[8:])
udp[8]==14 (14是十六进制0x14)匹配payload第一个字节0x14的UDP数据包
udp[8:2]==14:05 可以udp[8:2]==1405,且只支持2个字节连续,三个以上须使用冒号:分隔表示十六进制。 (相当于 udp[8]==14 and udp[9]==05,1405是0x1405)
udp[8:3]==22:00:f7 但是不可以udp[8:3]==2200f7
udp[8:4]==00:04:00:2a,匹配payload的前4个字节0x0004002a
而udp contains 7c:7c:7d:7d 匹配payload中含有0x7c7c7d7d的UDP数据包,不一定是从第一字节匹配。
udp[8:4] matches "\\x14\\x05\\x07\\x18"
udp[8:] matches "^\\x14\\x05\\x07\\x18\\x14"
5.2、搜索按条件过滤tcp的数据段payload(数字20是表示tcp头部有20个字节,数据部分从第21个字节开始tcp[20:])
tcp[20:] matches "^GET [ -~]*HTTP/1.1\\x0d\\x0a"
等同http matches "^GET [ -~]*HTTP/1.1\\x0d\\x0a"
tcp[20:] matches "^GET (.*?)HTTP/1.1\\x0d\\x0a"
tcp[20:] matches "^GET (.*?)HTTP/1.1\\x0d\\x0a[\\x00-\\xff]*Host: (.*?)pplive(.*?)\\x0d\\x0a"
tcp[20:] matches "^GET (.*?)HTTP/1.1\\x0d\\x0a[\\x00-\\xff]*Host: "
tcp[20:] matches "^POST / HTTP/1.1\\x0d\\x0a[\\x00-\\xff]*\\x0d\\x0aConnection: Keep-Alive\\x0d\\x0a\\x0d\\x0a"
检测SMB头的smb标记,指明smb标记从tcp头部第24byte的位置开始匹配。
tcp[24:4] == ff:53:4d:42
检测SMB头的smb标记,tcp的数据包含十六进制ff:53:4d:42,从tcp头部开始搜索此数据。
tcp contains ff:53:4d:42
tcp matches "\\xff\\x53\\x4d\\x42"
检测tcp含有十六进制01:bd,从tcp头部开始搜索此数据。
tcp matches "\\x01\\xbd"
检测MS08067的RPC请求路径
tcp[179:13] == 00:5c:00:2e:00:2e:00:5c:00:2e:00:2e:00
\ . . \ . .
5.3、其他
http.request.uri matches ".gif$" 匹配过滤HTTP的请求URI中含有".gif"字符串,并且以.gif结尾(4个字节)的http请求数据包($是正则表达式中的结尾表示符)
注意区别:http.request.uri contains ".gif$" 与此不同,contains是包含字符串".gif$"(5个字节)。匹配过滤HTTP的请求URI中含有".gif$"字符串的http请求数据包(这里$是字符,不是结尾符)
eth.addr[0:3]==00:1e:4f 搜索过滤MAC地址前3个字节是0x001e4f的数据包。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)