PE头
DOS头
64个字节
DOS-stub
PE头
Signature
FileHeader字段
1 | typedef struct _IMAGE_FILE_HEADER { |
OptionalHeader
1 | typedef struct _IMAGE_OPTIONAL_HEADER { |
节表
调试
找到程序入口点
经过动调,发现在执行了005A17D5
这条函数调用之后就弹出了notepad
,所以我们在这里下断点,步入调用继续调试
继续按照弹出程序与否继续调试,发现执行了0058D224
之后弹出了程序,于是步入调试
进入了窗口参数设置的代码,RegisterWindowMessageW
函数定义一个新的窗口消息
这里调用了CreatWindowExW
函数创建一个窗口
接下来的代码继续对窗口和进程的参数继续设置
最后,在执行了ShowWindow
函数调用之后,窗口弹出。
这里获取了桌面进程,并且获取了当前线程的线程ID
程序执行结束
修改notepad.exe
找到系统SYSTEM32目录下的user32.dll文件,用UltraEdit打开并分析该文件导出表,找出 MessageBoxA的地址,并验证该地址是否正确。
用PEview打开user32.dll
Name:保存了dll的名称
AddressOfFunctions:保存了所有导出函数的地址RVA
AddressOfNames:保存了所有按名称导出的函数的名称RVA
AddressOfNameOrdinals:保存了所有按名称导出的函数的序号
当我们要在导出表中查找某一个函数时,我们要先遍历AddressOfNames查找函数名称,记录当下的索引0。之后将索引0作为AddressOfNameOrdinals的索引值查找值,获得索引1,再将索引1作为AddressOfFunctions的索引找到函数地址的RVA
我们首先在AddressOfNames
里面找到MessageBoxA
然后0x0864-0x05E0
得到0x0284
,即为AddressOfNames
数组索引值
然后在AddressOfNameOrdinals
中查找序号值,找第0x0284
个表项
即MessageBoxA
的序号为0x0286
,然后在AddressOfFunctions
中找到函数地址0x06C1C0
即RVA
然后加载user32.dll
获得基址,基址为75B50000
,加上RVA,等于75BBC1C0
验证一下,结果正确