Author Archive

连连看算法

星期二, 27 9 月, 2011

强烈推荐:怎么写连连看 之 连连看算法

一个HelloWorld

星期五, 23 9 月, 2011

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反编译

星期四, 22 9 月, 2011

Invalid number of data directories in NT header

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

bochs

星期二, 20 9 月, 2011

[科普]在bochs虚拟机中安装WindowsXP

Bochs 仿真软件

用Bochs调试NTLDR

bochs中查看段寄存器使用sreg命令!

XP Boot Sector1

星期二, 20 9 月, 2011

XP.BS1即Windows XP启动分区中的第一个扇区,是继XP.MBR之后执行的代码。用老办法WinHex拷贝为新的二进制文件,debug -u反汇编之。分析了一段代码,坑爹的发现代码部分里面穿插了好多DB定义和奇怪的操作,然后就分析不下去了。我还以为是花指令或者为了填充到指定大小引起的呢。结果下午竟然用IDA折腾出来了。

IDA分析一段二进制的时候首先要确定这段二进制是代码,其次要选择好反汇编的CPU平台,最后需要在确定是代码的部分:右键—>分析指定区(不然你会看到全是DB定义,木有代码)。

先奉上我用debug -u分析的那段,虽然后面分析不下去,但前面能分析的部分大体是正确的。

XP.BS1

再奉上IDA分析过后的(需下载,并用IDA打开,就别直接点开看了)

XP.BS1(修正部分没在IDB里修正,sorry,看.txt吧)

最后方便没有IDA或想在线看IDA分析过后的(这个是从IDA文件中拷贝出来的,可以直接点开看)

XP.BS1.IDA(看后面的修正吧)

参考资料:活动分区的引导记录DBR分析加XP.MBR中的那些。

重要修正:怎么说呢,技术还很菜,难免疏漏。用bochs跟了遍,修正下.txt文档。

XP.BS1.IDA修正