首页
社区
课程
招聘
[原创]今天受了点刺激,用IDA反汇编了一个函数出出气,欢迎大牛们批评指导!
发表于: 2012-10-7 23:19 9253

[原创]今天受了点刺激,用IDA反汇编了一个函数出出气,欢迎大牛们批评指导!

2012-10-7 23:19
9253

转眼一晃,注册看雪已经7个月了,首先要感谢看雪学院的所有大牛们,从你们身上我学到了好多好多知识。
      我想模仿一个插件的全部功能,并自己完善它,这个插件用到了dirextX库,要反编译它,不是件容易的事,我今天就先反汇编了一下自己写的函数,先磨磨刀,等磨的差不多了就要实战了。
     废话不多说了,上源码,特别感谢一下fzhaoqiang,这个源码是跟这位仁兄学的。
     HRESULT CopyBmp(TCHAR* filename,IDirect3DDevice9* pDev)
{
        HRESULT hr;
        D3DDISPLAYMODE mode;
        IDirect3DSurface9* surf;
        if (FAILED(hr=pDev-> GetDisplayMode(0,&mode)))
                return hr;
        if (FAILED(hr=pDev->CreateOffscreenPlainSurface(mode.Width,mode.Height,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&surf,NULL)))
                return hr;
        if (FAILED(hr=pDev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_FORCE_DWORD,&surf)))
        {
                surf-> Release();
                return hr;
        }
        hr=D3DXSaveSurfaceToFile(filename,D3DXIFF_JPG,surf,NULL,NULL);
        surf-> Release();
        return hr;
}
IDA没有生成这个函数的流程图,所以也没发发出来了,可能是我还对IDA水平太差了。
以下是我对IDA反汇编代码的理解,请大家多多指教,我是新手,有错误的地方请大牛们别见笑。

.text:00412D50
.text:00412D50 loc_412D50:                             ; CODE XREF: .text:0041125Dj
.text:00412D50                 push    ebp                ;保存原堆指针
.text:00412D51                 mov     ebp, esp                ;ebp指向栈空间,
.text:00412D53                 sub     esp, 0F4h        ;开辟栈空间
.text:00412D59                 push    ebx                ;保存原栈顶
.text:00412D5A                 push    esi                ;保存esi
.text:00412D5B                 push    edi                ;保存edi
.text:00412D5C                 lea     edi, [ebp-0F4h]        ;edi指向栈顶        0xF4/0x4=61,61*4=124字节空间
.text:00412D62                 mov     ecx, 3Dh                ;设置初始化局部变量循环的次数,0xF4/0x4正好等于3Dh,very good终于明白了
.text:00412D67                 mov     eax, 0CCCCCCCCh        ;初始化前,eax就是0CCCCCCCCh,C++就是这样的
.text:00412D6C                 rep stosd                ;初始化局部变量
.text:00412D6E                 mov     eax, dword_42D180;取进程cookie,送入eax
.text:00412D73                 xor     eax, ebp                ;计算cookie保存在eax中
.text:00412D75                 mov     [ebp-4], eax        ;[ebp-4]保存cookie,函数返回前弹出,子程序执行完返回前,检查堆栈是否保持平衡
.text:00412D78                 mov     esi, esp                ;esi指向栈顶
.text:00412D7A                 lea     eax, [ebp-24h]        ;[ebp-24h]为D3DDISPLAYMODE mode;结构体的指针
.text:00412D7D                 push    eax                ;压入IDirect3DSurface9结构体指针mode
.text:00412D7E                 push    0                ;iSwapChain=0,入栈
.text:00412D80                 mov     ecx, [ebp+0Ch]       
.text:00412D83                 mov     edx, [ecx]        ;edx保存返回值hr
.text:00412D85                 mov     eax, [ebp+0Ch]       
.text:00412D88                 push    eax                ;hr入栈
.text:00412D89                 mov     ecx, [edx+20h]        ;[edx+20h]是IDirect3DDevice9::GetDisplayMode(UINT iSwapChain,D3DDISPLAYMODE *pMode)函数的指针
.text:00412D8C                 call    ecx                ;GetDisplayMode(0,&mode)
.text:00412D8E                 cmp     esi, esp                ;esi保存的是栈顶,而子函数调用中改变的是esp的值,所以比较esi和esp的值
.text:00412D90                 call    sub_41191F        ;然后call __RTC_CheckEsp()检查堆栈是否平衡
.text:00412D95                 mov     [ebp-0Ch], eax        ;返回hr,[ebp-0Ch]就是hr的地址
.text:00412D98                 cmp     dword ptr [ebp-0Ch], 0        ;判断hr是否大于等于0,大于等于0则成功
.text:00412D9C                 jge     short loc_412DA6        ;GetDisplayMode(0,&mode)获取显示模式成功,则跳转到0x412DA6
.text:00412D9E                 mov     eax, [ebp-0Ch]        ;return hr;所以要eax要保存hr的值
.text:00412DA1                 jmp     loc_412E59        ;GetDisplayMode(0,&mode)获取显示模式失败,函数就返回,返回hr的值
.text:00412DA6 ; ---------------------------------------------------------------------------
.text:00412DA6
.text:00412DA6 loc_412DA6:                             ; CODE XREF: .text:00412D9Cj
.text:00412DA6                 mov     esi, esp                ;esi指向栈顶
.text:00412DA8                 push    0                ;HANDLE *pSharedHandle=NULL,获取的是屏幕的离屏表面
.text:00412DAA                 lea     eax, [ebp-30h]
.text:00412DAD                 push    eax                ;IDirect3DSurface9 **ppSurface;
.text:00412DAE                 push    2                ;D3DPOOL Pool=D3DPOOL_SYSTEMMEM;
.text:00412DB0                 push    15h                ;D3DFORMAT Format=D3DFMT_A8R8G8B8;
.text:00412DB2                 mov     ecx, [ebp-20h]
.text:00412DB5                 push    ecx                ;UINT Height=mode.Height;
.text:00412DB6                 mov     edx, [ebp-24h]
.text:00412DB9                 push    edx                ;UINT Width=mode.Width;
.text:00412DBA                 mov     eax, [ebp+0Ch]
.text:00412DBD                 mov     ecx, [eax]        ;ecx保存返回值hr
.text:00412DBF                 mov     edx, [ebp+0Ch]       
.text:00412DC2                 push    edx                ;hr入栈
.text:00412DC3                 mov     eax, [ecx+90h]                ;[ecx+90h]为IDirect3DDevice9::CreateOffscreenPlainSurface函数的指针
.text:00412DC9                 call    eax                        ;CALL CreateOffscreenPlainSurface
.text:00412DCB                 cmp     esi, esp                        ;同上.text:00412D8E  
.text:00412DCD                 call    sub_41191F                ;同上.text:00412D90,检查堆栈是否平衡
.text:00412DD2                 mov     [ebp-0Ch], eax                ;返回hr
.text:00412DD5                 cmp     dword ptr [ebp-0Ch], 0        ;判断CreateOffscreenPlainSurface函数获取离屏表面是否成功
.text:00412DD9                 jge     short loc_412DE0                ;成功,则跳转到0x412DA6
.text:00412DDB                 mov     eax, [ebp-0Ch]                ;return hr;所以要eax要保存hr的值
.text:00412DDE                 jmp     short loc_412E59                ;CreateOffscreenPlainSurface函数失败,函数就返回,返回hr的值
.text:00412DE0 ; ---------------------------------------------------------------------------
.text:00412DE0
.text:00412DE0 loc_412DE0:                             ; CODE XREF: .text:00412DD9j
.text:00412DE0                 mov     esi, esp                        ;esi指向栈顶
.text:00412DE2                 lea     eax, [ebp-30h]                ;[ebp-30h]是IDirect3DSurface9指针surf的地址
.text:00412DE5                 push    eax                        ;IDirect3DSurface9 **ppBackBuffer=&surf;
.text:00412DE6                 push    7FFFFFFFh                ;D3DBACKBUFFER_TYPE Type=D3DBACKBUFFER_TYPE_FORCE_DWORD;
.text:00412DEB                 push    0                        ;UINT BackBuffer=NULL;
.text:00412DED                 push    0                        ;UINT  iSwapChain=NULL;
.text:00412DEF                 mov     ecx, [ebp+0Ch]
.text:00412DF2                 mov     edx, [ecx]                ;ecx保存返回值hr
.text:00412DF4                 mov     eax, [ebp+0Ch]
.text:00412DF7                 push    eax                        ;返回值hr入栈
.text:00412DF8                 mov     ecx, [edx+48h]                ;ecx保存[edx+48h]不知道是干什么的
.text:00412DFB                 call    ecx                        ;call IDirect3DDevice9::GetBackBuffer获取后台图像数据
.text:00412DFD                 cmp     esi, esp                        ;同上.text:00412D8E  
.text:00412DFF                 call    sub_41191F                ;同上.text:00412D90,检查堆栈是否平衡
.text:00412E04                 mov     [ebp-0Ch], eax                ;保存返回值hr
.text:00412E07                 cmp     dword ptr [ebp-0Ch], 0   ;判断GetBackBuffer函数获取离屏表面是否成功
.text:00412E0B                 jge     short loc_412E29                ;GetBackBuffer函数失败,函数就返回,返回hr的值
.text:00412E0D                 mov     eax, [ebp-30h]                ;[ebp-30h]是IDirect3DSurface9指针surf的地址,从00412DE2行GetBackBuffer函数的最后参数判断出
.text:00412E10                 mov     ecx, [eax]                ;ecx保存surf指针
.text:00412E12                 mov     esi, esp                        ;esi指向栈顶
.text:00412E14                 mov     edx, [ebp-30h]                ;edx保存IDirect3DSurface9结构体指针surf
.text:00412E17                 push    edx                        ;IDirect3DSurface9结构体指针surf入栈
.text:00412E18                 mov     eax, [ecx+8]                ;surf指针+8h为IDirect3DSurface9::Release()函数的指针
.text:00412E1B                 call    eax                        ;CALL IDirect3DSurface9::Release();
.text:00412E1D                 cmp     esi, esp                        ;同上.text:00412D8E  
.text:00412E1F                 call    sub_41191F                ;同上.text:00412D90,检查堆栈是否平衡
.text:00412E24                 mov     eax, [ebp-0Ch]                ;保存返回值hr
.text:00412E27                 jmp     short loc_412E59                ;Release()函数执行完,函数就返回
.text:00412E29 ; ---------------------------------------------------------------------------
.text:00412E29
.text:00412E29 loc_412E29:                             ; CODE XREF: .text:00412E0Bj
.text:00412E29                 push    0                                ;const RECT *pSrcRect=NULL;
.text:00412E2B                 push    0                                ;const PALETTEENTRY *pSrcPalette=NULL;
.text:00412E2D                 mov     eax, [ebp-30h]
.text:00412E30                 push    eax                                ;IDirect3DSurface9结构体指针surf
.text:00412E31                 push    1                                ;D3DXIMAGE_FILEFORMAT DestFormat=D3DXIFF_JPG;
.text:00412E33                 mov     ecx, [ebp+8]
.text:00412E36                 push    ecx                                ;LPCTSTR pDestFile这是要保存的图片绝对路径名
.text:00412E37                 call    j_D3DXSaveSurfaceToFileW                ;这个函数ida直接识别出来了
.text:00412E3C                 mov     [ebp-0Ch], eax                        ;保存返回值hr
.text:00412E3F                 mov     eax, [ebp-30h]
.text:00412E42                 mov     ecx, [eax]                        ;ecx保存IDirect3DSurface9结构体指针surf
.text:00412E44                 mov     esi, esp                                ;esi指向栈顶
.text:00412E46                 mov     edx, [ebp-30h]
.text:00412E49                 push    edx                                ;IDirect3DSurface9结构体指针surf入栈
.text:00412E4A                 mov     eax, [ecx+8]
.text:00412E4D                 call    eax                                ;CALL IDirect3DSurface9::Release();
.text:00412E4F                 cmp     esi, esp                ;同上.text:00412D8E  
.text:00412E51                 call    sub_41191F        ;同上.text:00412D90,检查堆栈是否平衡
.text:00412E56                 mov     eax, [ebp-0Ch]        ;保存返回值hr
.text:00412E59
.text:00412E59 loc_412E59:                             ; CODE XREF: .text:00412DA1j
.text:00412E59                                         ; .text:00412DDEj ...
.text:00412E59                 push    edx      ;这里为什么要入栈保存edx,edx里应该是什么值还没想明白
.text:00412E5A                 mov     ecx, ebp ;ecx保存栈顶指针
.text:00412E5C                 push    eax     ;保存函数返回值
.text:00412E5D                 lea     edx, dword_412E88;再次取出进程cookie,送入eax
.text:00412E63                 call    sub_411401        ;CALL _RTC_CheckStackVars这个函数,从字面意思理解是检查堆参数,不明白还请大牛指点
.text:00412E68                 pop     eax                ;恢复返回值hr到eax
.text:00412E69                 pop     edx                ;恢复edx
.text:00412E6A                 pop     edi                ;恢复原edi
.text:00412E6B                 pop     esi              ;恢复原esi
.text:00412E6C                 pop     ebx                ;恢复原ebx
.text:00412E6D                 mov     ecx, [ebp-4]        ;对应00412D75行 弹出cookie到ecx,函数返回前弹出,子程序执行完返回前,检查堆栈是否保持平衡
.text:00412E70                 xor     ecx, ebp                ;取进程cookie值,保存在ecx
.text:00412E72                 call    sub_411154        ;CALL __security_check_cookie函数检查堆栈是否保持平衡
.text:00412E77                 add     esp, 0F4h        ;释放函数申请的栈空间
.text:00412E7D                 cmp     ebp, esp                ;同上.text:00412D8E
.text:00412E7F                 call    sub_41191F        ;同上.text:00412D90,检查堆栈是否平衡
.text:00412E84                 mov     esp, ebp                ;恢复原esp
.text:00412E86                 pop     ebp                ;恢复原ebx,ebx重新指向堆函数调用在堆中的位置
.text:00412E87                 retn                        ;函数返回
.


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 6
支持
分享
最新回复 (12)
雪    币: 297
活跃值: (120)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
学习逆向就要学会享受孤独
2012-10-7 23:47
0
雪    币: 297
活跃值: (120)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
我郁闷,为什么我总是这么孤独,有好几个地方还不明白呢
2012-10-8 15:46
0
雪    币: 235
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
啊~好像很牛逼,顶,你并不孤独
2012-10-8 15:50
0
雪    币: 297
活跃值: (120)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
我就是把以前学的那些东西,一下都综合起来,真正的分析了一次
      有很多地方,分析的对不对我自己也不确定,咋就没大牛指点一下呢。
      最后返回哪个edx里面存的是什么,为什么要push保存一次我想不通。
      还有_RTC_CheckStackVars这个CALL到底是干啥用的,我就是字面意思分析,根本没完全搞懂。
2012-10-8 16:02
0
雪    币: 1737
活跃值: (110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
大牛们都很忙的。。。
2012-10-8 16:51
0
雪    币: 1737
活跃值: (110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
“今天受了点刺激,用IDA反汇编了一个函数出出气”
佩服作者这种化压力为动力的方法。。。
2012-10-8 16:53
0
雪    币: 8201
活跃值: (2701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
其余看不懂
.text:00412D67                 mov     eax, 0CCCCCCCCh  ;初始化前,eax就是0CCCCCCCCh,C++就是这样的
这句是vc 的debug模式的常见做法,写入int 3吧?
2012-10-8 18:25
0
雪    币: 297
活跃值: (120)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
呵呵,你说的对,函数开始的时候会把堆栈中的每个字节初始化为0cch,这样发生意外时,执行到堆栈里的代码时,会出触发调试中断。
谢谢,纠正了我的错误理解。
2012-10-9 00:07
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
好像很牛逼,顶,你并不孤独
2012-10-9 08:57
0
雪    币: 297
活跃值: (120)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
牛逼的人都在虐各种游戏保护,破解各种软件,研究各种变态的保护呢。
2012-10-9 09:25
0
雪    币: 345
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
游戏保护都是浮云撒
2012-10-9 09:26
0
雪    币: 15
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
看不懂的帮顶吧
2012-10-14 22:38
0
游客
登录 | 注册 方可回帖
返回
//