|
我从事汇编语言研究大概几年前,因为是我为了开发sepl计算机语言编译器。虽然到现在还没有开发出来,但是已经看到曙光了。为了研究汇编,我从反汇编入手,做了破解,脱壳,调试等。
但是汇编对我来说一直是读天书,没有任何突破。直到最近几天我有了重大发现。有人说做黑客从反汇编sqlserver.exe文件开始,可是在数以百万计的汇编代码丛林中,你能看到什么呢?能读懂么?
直到最近看了一本win32汇编书籍,他里面说可以把vc程序反汇编,获得汇编程序。如果随便用ida反汇编,如过没有把原程序和汇编放在一起,那么仍然没有收获。我按照说明操作了终于得到原程序和汇编放在一起的文件,就像在调试状态一样,每个c语言程序对应一个扩展名叫.cod文件.用它来学习真是大爽,天书变成可破解的代码!
具体做法是打开vc项目,选择菜单project->setting,在对话框选择c/c++页,然后category中选择Listing Files,在下面Listing file type选择 Assambly,machine code,and Source,确定退出。
现在编译程序,在release/debug目录下面生成对应的cod文件,包含有汇编,机器码和源代码。
通过阅读cod文件,你将很快了解汇编,你会发现原程序和汇编并不完全一一对应,当并不妨碍你分析汇编。
如果你不停的阅读和学习cod,也许一个月后你就会成为反汇编高手了!目前我刚开始2天。我决定坚持一个月。
文件Base64.cod内容如下
TITLE E:\cryptoLib\Base64.cpp .386P include listing.inc if @Version gt 510 .model FLAT else _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' _TEXT ENDS _DATA SEGMENT DWORD USE32 PUBLIC 'DATA' _DATA ENDS CONST SEGMENT DWORD USE32 PUBLIC 'CONST' CONST ENDS _BSS SEGMENT DWORD USE32 PUBLIC 'BSS' _BSS ENDS _TLS SEGMENT DWORD USE32 PUBLIC 'TLS' _TLS ENDS ; COMDAT ??_C@_0BB@NAAD@Magellan?5MSWHEEL?$AA@ _DATA SEGMENT DWORD USE32 PUBLIC 'DATA' _DATA ENDS ; COMDAT ??_C@_06FPAF@MouseZ?$AA@ _DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
..................
; COMDAT ??_7?$basic_ostream@DU?$char_traits@D@std@@@std@@6B@ CONST SEGMENT DWORD USE32 PUBLIC 'CONST' CONST ENDS ; COMDAT ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB CONST SEGMENT DWORD USE32 PUBLIC 'CONST' CONST ENDS FLAT GROUP _DATA, CONST, _BSS, CRT$XCA, CRT$XCU, CRT$XCL, CRT$XCC, CRT$XCZ, xdata$x ASSUME CS: FLAT, DS: FLAT, SS: FLAT endif CONST SEGMENT _EnBase64Tab DB 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123' DB '456789+/', 00H ORG $+3 _DeBase64Tab DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 03eH DB 00H DB 00H DB 00H DB 03fH DB 034H DB 035H DB 036H DB 037H DB 038H DB 039H DB 03aH DB 03bH DB 03cH DB 03dH DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 01H DB 02H DB 03H DB 04H DB 05H DB 06H DB 07H DB 08H DB 09H DB 0aH DB 0bH DB 0cH DB 0dH DB 0eH DB 0fH DB 010H DB 011H DB 012H DB 013H DB 014H DB 015H DB 016H DB 017H DB 018H DB 019H DB 00H DB 00H DB 00H DB 00H DB 00H DB 00H DB 01aH DB 01bH DB 01cH DB 01dH DB 01eH DB 01fH DB 020H DB 021H DB 022H DB 023H DB 024H DB 025H DB 026H DB 027H DB 028H DB 029H DB 02aH DB 02bH DB 02cH DB 02dH DB 02eH DB 02fH DB 030H DB 031H DB 032H DB 033H CONST ENDS CRT$XCU SEGMENT _$S384 DD FLAT:_$E383 CRT$XCU ENDS PUBLIC ?EncodeBase64@@YAHPBEPADH@Z ; EncodeBase64 ; COMDAT ?EncodeBase64@@YAHPBEPADH@Z _TEXT SEGMENT _pSrc$ = 8 _pDst$ = 12 _nSrcLen$ = 16 _c1$ = 12 _c2$ = 8 _c3$ = 16 _nMod$ = -4 ?EncodeBase64@@YAHPBEPADH@Z PROC NEAR ; EncodeBase64, COMDAT
; 7 : {
00000 51 push ecx 00001 55 push ebp 00002 56 push esi
; 8 : unsigned char c1, c2, c3; // 输入缓冲区读出3个字节 ; 9 : int nDstLen = 0; // 输出的字符计数 ; 10 : int nDiv = nSrcLen / 3; // 输入数据长度除以3得到的倍数
00003 8b 74 24 18 mov esi, DWORD PTR _nSrcLen$[esp+8] 00007 b8 56 55 55 55 mov eax, 1431655766 ; 55555556H 0000c f7 ee imul esi 0000e 8b c2 mov eax, edx 00010 33 ed xor ebp, ebp 00012 c1 e8 1f shr eax, 31 ; 0000001fH 00015 03 d0 add edx, eax
; 11 : int nMod = nSrcLen % 3; // 输入数据长度除以3得到的余数
00017 8b c6 mov eax, esi 00019 8b ca mov ecx, edx 0001b be 03 00 00 00 mov esi, 3 00020 99 cdq 00021 f7 fe idiv esi
; 12 : ; 13 : // 每次取3个字节,编码成4个字符 ; 14 : for (int i = 0; i < nDiv; i ++)
00023 85 c9 test ecx, ecx 00025 89 54 24 08 mov DWORD PTR _nMod$[esp+12], edx 00029 0f 8e dc 00 00 00 jle $L132338 0002f 8b 44 24 14 mov eax, DWORD PTR _pDst$[esp+8] 00033 53 push ebx 00034 8b d9 mov ebx, ecx 00036 8d 2c 8d 00 00 00 00 lea ebp, DWORD PTR [ecx*4] 0003d 8b 4c 24 14 mov ecx, DWORD PTR _pSrc$[esp+12] 00041 57 push edi $L129542:
; 15 : { ; 16 : // 取3个字节 ; 17 : c1 = *pSrc++;
00042 8a 11 mov dl, BYTE PTR [ecx] 00044 41 inc ecx 00045 88 54 24 1c mov BYTE PTR _c1$[esp+16], dl
; 18 : c2 = *pSrc++;
00049 8a 11 mov dl, BYTE PTR [ecx]
; 19 : c3 = *pSrc++; ; 20 : ; 21 : // 编码成4个字符 ; 22 : *pDst++ = EnBase64Tab[c1 >> 2];
0004b 8b 74 24 1c mov esi, DWORD PTR _c1$[esp+16] 0004f 41 inc ecx 00050 88 54 24 18 mov BYTE PTR _c2$[esp+16], dl
; 23 : *pDst++ = EnBase64Tab[((c1 << 4) | (c2 >> 4)) & 0x3f];
00054 8b 7c 24 18 mov edi, DWORD PTR _c2$[esp+16] 00058 81 e6 ff 00 00 00 and esi, 255 ; 000000ffH 0005e 8a 11 mov dl, BYTE PTR [ecx] 00060 81 e7 ff 00 00 00 and edi, 255 ; 000000ffH 00066 88 54 24 20 mov BYTE PTR _c3$[esp+16], dl 0006a 8b d6 mov edx, esi 0006c c1 ea 02 shr edx, 2 0006f 83 e6 03 and esi, 3 00072 41 inc ecx 00073 8a 92 00 00 00 00 mov dl, BYTE PTR _EnBase64Tab[edx] 00079 88 10 mov BYTE PTR [eax], dl 0007b 8b d7 mov edx, edi 0007d c1 ea 04 shr edx, 4 00080 c1 e6 04 shl esi, 4 00083 0b d6 or edx, esi
; 24 : *pDst++ = EnBase64Tab[((c2 << 2) | (c3 >> 6)) & 0x3f];
00085 8b 74 24 20 mov esi, DWORD PTR _c3$[esp+16] 00089 40 inc eax 0008a 81 e6 ff 00 00 00 and esi, 255 ; 000000ffH 00090 8a 92 00 00 00 00 mov dl, BYTE PTR _EnBase64Tab[edx] 00096 83 e7 0f and edi, 15 ; 0000000fH 00099 88 10 mov BYTE PTR [eax], dl 0009b 8b d6 mov edx, esi 0009d c1 ea 06 shr edx, 6 000a0 c1 e7 02 shl edi, 2 000a3 0b d7 or edx, edi 000a5 40 inc eax
; 25 : *pDst++ = EnBas |