教你如何分析undocumented的数据结构

来源:x86asm.com  hsly110 

1 前言:

  这2天看了Secrets of Reverse Engineering一书,对分析未文档化的API的技术比较有心得,希望各位看了下面的教程,能抛砖引玉灵活的应用在逆向工程和破解技术上,方法是死的,但是人的思维是活,最重要是灵活应用。

  2 实践:

  用OllyDbg对NTDLL.DLL进行反汇编,前提你要加入NTDLL.DLL的符号表,这样你才能更好的对未文档化的API进行反汇编,你们到微软官方网站获取相应版本Windows系统的系统符号表。

  下面是RtlInitializeGenericTable函数的反汇编代码:

  01 MOV EDI, EDI ;

  //压入堆栈,保存EBP的数值

  02 PUSH EBP ;              

  03 MOV EBP, ESP ;

  // 获取[ESP+8]的数值传入EAX

  // 此处指令我们可以翻译为:

  // MOV EAX, DWORD PTR SS:[ESP+8]

  // 含义: 把当前堆栈顶向下偏移8h处的值赋给EAX,也就是该函数的第1个参数

  // 声明:我喜欢用ESP指针来想象堆栈。但是CPU处理的话,是用EBP来进行偏移处理

  04 MOV EAX, DWORD PTR SS:[EBP+8] ;

  05 XOR EDX, EDX ;

  // EAX+4的数值当作指针传入ECX

  06 LEA ECX, DWORD PTR DS:[EAX+4] ;

  // EDX的数值传入[EAX],说明EAX的值是某个结构的指针

  // 假设pUnknowStruct的地址为 EAX的数值

  // 07的汇编指令对应的C语言: pUnknowStruct->member1 = 0 ;

  07 MOV DWROD PTR DS:[EAX], EDX ;

  // 此处指令我们可以翻译为:

  // MOV DWORD PTR DS:[EAX+8], EAX+4 ;

  // 备注: [EAX] 为某结构的第1个变量

  // [EAX+4]为某结构的第2个变量

  // [EAX+8]为某结构的第3个变量

  // 含义:该结构的第3个成员变量被赋于指向该结构的第2个成员变量的指针数值

  // 08的汇编指令对应的C语言: pUnknowStruct->member3 = &pUnknowStruct->member2

  08 MOV DWORD PTR DS:[ECX+4], ECX ;

  // 此处指令我们可以翻译为:

  // MOV DWORD PTR DS:[EAX+4], EAX+4 ;

  // 09的汇编指令对应的C语言: pUnknowStruct->member2 = &pUnknowStruct->member2

  09 MOV DWORD PTR DS:[ECX], ECX ;

  // 此处指令我们可以翻译为:

  // MOV DWORD PTR DS:[EAX+C], EAX+4 ;

  // 10的汇编指令对应的C语言: pUnknowStruct->member4 = &pUnknowStruct->member2

  10 MOV DWORD PTR DS:[EAX+C], ECX ;

 // 此处指令我们可以翻译为:

  // MOV ECX, DWORD PTR SS:[ESP+C]

  // 含义: 把当前堆栈顶向下偏移Ch处的值赋给ECX,也就是该函数的第2个参数

  11 MOV ECX, DWORD PTR SS:[EBP+C] ;

  // 含义: 把第2个参数传送给某结构的第7个成员变量

  // 12的汇编指令对应的C语言为: pUnknowStruct->member7 = Param2

  12 MOV DWORD PTR DS:[EAX+18], ECX ;

  // 此处指令我们可以翻译为:

  // MOV ECX, DWORD PTR SS:[ESP+10]

  // 含义: 把当前堆栈顶向下偏移10h处的值赋给ECX,也就是该函数的第3个参数

  13 MOV ECX, DWORD PTR SS:[EBP+10] ;

  // 含义:把参数3传给某结构的第8个成员变量

  // 14的汇编指令对应的C语言为: pUnknowStruct->member8 = Param3

  14 MOV DWORD PTR DS:[EAX+1C], ECX ;

  // 此处指令我们可以翻译为:

  // MOV ECX, DWORD PTR SS:[ESP+14]

  // 含义: 把当前堆栈顶向下偏移14h处的值赋给ECX,也就是该函数的第4个参数

  15 MOV ECX, DWORD PTR SS:[EBP+14] ;

  // 含义:把参数3传给某结构的第9个成员变量

  // 16的汇编指令对应的C语言为: pUnknowStruct->member9 = Param4

  16 MOV DWORD PTR DS:[EAX+20], ECX ;

  // 此处指令我们可以翻译为:

  // MOV ECX, DWORD PTR SS:[ESP+18]

  // 含义: 把当前堆栈顶向下偏移18h处的值赋给ECX,也就是该函数的第5个参数

  17 MOV ECX, DWORD PTR SS:[EBP+18] ;

  // 含义:把EDX的数值赋给某结构的第6个成员变量

  // 18的汇编指令对应的C语言为: pUnknowStruct->member6 = 0

  18 MOV DWORD PTR DS:[EAX+14], EDX ;

  // 含义:把EDX的数值赋给某结构的第6个成员变量

  // 19的汇编指令对应的C语言为: pUnknowStruct->member5 = 0

  19 MOV DWORD PTR DS:[EAX+10], EDX ;

  // 含义:把参数5传给某结构的第10个成员变量

  // 29的汇编指令对应的C语言为: pUnknowStruct->member10 = Param5

  20 MOV DWORD PTR DS:[EAX+24], ECX ;

  21 POP EBP

  22 RET 14

  3 逆出伪代码:

  说明: 反汇编分析出如下关键指令

  04 MOV EAX, DWORD PTR SS:[EBP+8] ;

  11 MOV ECX, DWORD PTR SS:[EBP+C] ;

  13 MOV ECX, DWORD PTR SS:[EBP+10] ;

  15 MOV ECX, DWORD PTR SS:[EBP+14] ;

  17 MOV ECX, DWORD PTR SS:[EBP+18] ;

可以看得出,该函数使用了5个参数,可以假设为: Param1...5 ;struct UnknowStruct
{
  UNKNOWN Member1 ;
  UNKNOWN_PTR Member2 ;
  UNKNOWN_PTR Member3 ;
  UNKNOWN_PTR Member4 ;
  UNKNOWN Member5 ;
  UNKNOWN Member6 ;
  UNKNOWN Member7 ;
  UNKNOWN Member8 ;
  UNKNOWN Member9 ;
  UNKNOWN Member10 ;
} ;
struct UnknowStruct *pUnknowStruct ;
pUnknowStruct = Param1 ;
pUnknowStruct->Member1 = 0 ;
pUnknowStruct->Member3 = &pUnknowStruct->Member2 ;
pUnknowStruct->Member2 = &pUnknowStruct->Member2 ;
pUnknowStruct->Member4 = &pUnknowStruct->Member2 ;
pUnknowStrcut->Member7 = Param2 ;
pUnknowStruct->Member8 = Param3 ;
pUnknowStruct->Member9 = Param4 ;
pUnknowStruct->Member6 = 0
pUnknowStruct->Member5 = 0
pUnknowStruct->Member10 = Param5 ;

  4: 图片分析流程

  获取参数流程图

  

  结构赋值流程图

  

  5:总结

 经过反汇编分析,虽然只有22行代码,但是完成了这个结构的初始化工作,该结构的指针存放在EAX寄存器,赋值时,就是对EAX存放的地址进行偏移处理。大家可以查看流程图来思考一下。

  6:遗憾

  由于时间有限,未能写出下一篇: 教你如何分析结构成员变量的类型

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值