Archive for the ‘逆向’ Category

aliedit

最近有需要研究下支付宝的密码控件,即aliedit。谷歌百度之,发现还有驱动级别的(::>_<::)。自己动手,丰衣足食。
先看下支付宝的登录源码,其中有这样一段:alipay

OK,载体是一个ActiveX控件。不用浏览器安装这个ActiveX控件,直接从官网上下载aliedit.exe。
使用Universal Extractor将安装包解包,发现其中只有dll,看来并没有网上所说的驱动了(后面使用工具反复找也没找到驱动模块的痕迹)。
在Ring3的aliedit是如何处理键盘消息并防止被hook键盘消息的呢?
使用spy++捕捉支付宝页面的键盘消息,发现就只有aliedit控件处的键盘消息是无法捕捉到的,怀疑也是hook。
于是用工具找找hooks看,出于意料的是QQ管家、spy++等的hooks都被检查出来了,aliedit却没有(囧rz),只能看看其内部实现了。

直接用IDA打开发现IDA报警告,分析出的代码含UPX节,可能是加壳了。PEiD查壳果然,用UPX脱之,不费力。
在IDA的Imports中果然找到了SetWindowsHookEx和UnhookWindowsHookEx的引用,主要就是分析引用它们的例程了,分别是offset 0x936D和offset 0x93BC。

.text:100093A1 push 0 ; dwThreadId
.text:100093A3 push eax ; hmod
.text:100093A4 push offset fn ; lpfn
.text:100093A9 push 0Dh ; idHook
.text:100093AB call ds:SetWindowsHookExA

是一个全局的低级键盘钩子,奇怪的是我用工具没找到它的踪影——要么应该在工具中列出该钩子,要么在运行aliedit之后运行的进程中会有aliedit.dll模块。

IDA具体的分析如下:aliedit.idb(附件太大就不传了)

这里我只说说为什么会找不到aliedit的钩子。
先用OD附加打开了支付宝登录页面的IE,查看--->可执行模块中找到aliedit.dll的路径(C:\WINDOWS\system32\aliedit\2.5.0.3\aliedit.dll),用脱壳后的文件替换,然后再如上附加。
查看--->可执行模块中找到aliedit.dll的基址(07780000),查看--->内存中找到aliedit.dll的基址处,在代码节下断,然后运行。程序很快就会在aliedit.dll的领空断下来。
在0778936D(引用SetWindowsHookEx的例程)和077893BC(引用UnhookWindowsHookEx的例程)处下断,运行,总结:
aliedit控件获得焦点时会SetWindowsHookEx,反之,失去焦点时会UnhookWindowsHookEx。注意这里是aliedit控件,不是整个alipay的页面或IE。
这就解释了为什么用一般工具找不到它的hook了。

补充一个调用aliedit的测试页面:aliedit_test.html

一个HelloWorld

VS2003 Debug配置编译了一个HelloWorld程序,主要代码如下:
int main()
{
 printf("Hello, world!\n");
 return 0;
}

用OD调试来学习一下它的运行机理。OD载入,程序停在如下位置:
00411339 > $ /E9 F2080000   jmp     mainCRTStartup

用LordPE查看下PE文件,发现镜像基址:00400000,入口点:00011339,00400000+00011339=00411339看来OD停在了入口点。

入口点jmp mainCRTStartup以及mainCRTStartup很明显是由编译器生成的。单步跟进mainCRTStartup或者在IDA中查看mainCRTStartup可以看到,在调用用户代码前后它都做了很多工作。
用户代码的调用点如下:
.text:00411D9B                 call    j__main

j_main也是由编译器生成的一小段存根代码,如下:
.text:004113BB ; int __cdecl j__main()
.text:004113BB j__main         proc near
.text:004113BB                 jmp     _main
.text:004113BB j__main         endp

为什么会这样?应该是库代码的框架是确定的,已经生成了obj?lib?or dll?但是用户代码的位置在链接前是不确定的(因为在不同的obj模块),通过这种存根的方法就能解决问题。

库代码和用户代码最终都被链接合并到了同一个exe文件中,如果是exe和dll之间的调用关系又该如何呢?
首先必须要知道要使用哪个dll的哪个函数,然后加载dll获取函数的地址,最后call或者jmp到函数中去。
PE的文件格式已经解决了如上问题。数据目录中的输入表目录指示了要使用哪个dll、该dll中有哪些导出函数以及在哪个位置保存这些导出函数的地址(IAT)。

HelloWorld.exe的输入表如图:

注意其FirstThunk的RVA:0002A17C,和数据目录的IAT RVA一致。打开IAT也可以发现其大小为4*62(kernel32.dll中有62个导出函数)用于保存函数地址。Windows Loader在加载dll的时候会负责正确地填充。

这样一来,可以说PE文件已经准备好了一切,调用dll变得简单call or jmp [IAT中对应函数的地址的偏移]。但这里依然有两种方式可选,一种是高效率的call [],另一种是低效率的存根方法(call 存根; 存根: jmp [];)。

IDA中可以发现类似如下代码:
.text:00411C79                 call    ds:__imp__GetVersionExA@4 ; GetVersionExA(x)
.text:004112D0 ; [00000005 BYTES: COLLAPSED FUNCTION GetVersionExA(x). PRESS KEYPAD "+" TO EXPAND]

它们分别对应着前面提到的两种选择,可见对一个导出函数的调用,编译器生成了两种可选方案,只是HelloWorld中最终没有发现有调用.text:004112D0处的代码。
虽然编译器生成了两种可选方案,但是可以对输入的dll导出函数加上__desclspec(dllexport)修饰符,就能在调用时使用高效率的方案。

main中的代码没有什么好解释的,提一下在main恢复堆栈后切换栈帧前,有如下代码:
.text:00411A60                 add     esp, 0C0h
.text:00411A66                 cmp     ebp, esp
.text:00411A68                 call    j___RTC_CheckEsp
.text:00411A6D                 mov     esp, ebp
.text:00411A6F                 pop     ebp
很明显j___RTC_CheckEsp堆栈平衡检查,但好像与securty cookie不同,并不会影响缓冲区溢出漏洞。

.net反编译

Invalid number of data directories in NT header

Reflector Error:Module '…' contains zero or multiple module definitions.(没彻底明白怎么改,所以失败了,::>_<::)

一个CrackMe

CrackMe地址:http://bbs.pediy.com/showthread.php?t=139622

PEiD查壳:

 

 

 

 

 

 

 

 

ESP定律脱壳:pushad过后,esp为0x12FF96,此处下硬件断点(Command中输入hr 12FF96,并在调试/硬件断点中查看)。

 

 

 

 

 

F9运行到断点,发现0x40510B处jmp 0x401000,即为OEP。来到0x401000处发现乱码,右键--->分析/分析代码即可。

设消息断点:删除硬件断点,F9让程序运行起来。菜单--->查看/窗口,找到“确定”按钮,右键--->设消息断点,设置WM_LBUTTONUP的消息断点。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

输入帐号和密码并“确定”,程序断在系统领空,此时无法使用Ctrl+F9返回或Alt+F9返回到用户领空,Alt+M为CrackMe的整个.text代码段下内存访问断点,再F9就会停在消息处理例程(乱码则右键--->分析/分析代码)。

Read more

RegisterClass

 

 

 

 

 

 

 

 

 

 

 

 

RegisterClass逆向

http://bbs.pediy.com/showthread.php?t=139853

无觅相关文章插件,快速提升流量