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

验证一下,结果正确
