睡觉前习惯性浏览下看雪,一看到是新手练习用,就没睡意了。新手笔记奉上

出处:http://bbs.pediy.com/showthread.php?t=96997

od载入后

代码:
0101988A >  E8 00000000     CALL NOTEPAD.0101988F  //近跳转jmp,F7
0101988F    5B              POP EBX
01019890    81EB 05000000   SUB EBX,5
01019896    8B93 9F080000   MOV EDX,DWORD PTR DS:[EBX+89F]
0101989C    53              PUSH EBX
0101989D    6A 40           PUSH 40
0101989F    68 00100000     PUSH 1000
010198A4    52              PUSH EDX
010198A5    6A 00           PUSH 0
010198A7    FF93 32080000   CALL DWORD PTR DS:[EBX+832]   //F4到这,kernel32.VirtualAlloc申请内存,EAX=00A00000(返回的地址),应该是把要解压后的东西放到这里;F8跳过
010198AD    5B              POP EBX
010198AE    8BF0            MOV ESI,EAX
010198B0    8BBB 9B080000   MOV EDI,DWORD PTR DS:[EBX+89B]
010198B6    03FB            ADD EDI,EBX
010198B8    56              PUSH ESI //esi = 00A00000,刚申请到的内存
010198B9    57              PUSH EDI //edi = 0101A1EE,loadpe查看是.rsrc区块
010198BA    E8 86080000     CALL NOTEPAD.0101A145//F8到这里;快到retn了,F7进去吧
010198BF    83C4 08         ADD ESP,8
010198C2    8D93 BB080000   LEA EDX,DWORD PTR DS:[EBX+8BB]
010198C8    52              PUSH EDX
010198C9    53              PUSH EBX
010198CA    56              PUSH ESI
010198CB    C3              RETN
来到这里:
代码:
0101A145    60              PUSHAD
0101A146    8B7424 24       MOV ESI,DWORD PTR SS:[ESP+24]
0101A14A    8B7C24 28       MOV EDI,DWORD PTR SS:[ESP+28]
0101A14E    FC              CLD
0101A14F    B2 80           MOV DL,80
0101A151    33DB            XOR EBX,EBX
0101A153    A4              MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0101A154    B3 02           MOV BL,2
0101A156    E8 6D000000     CALL NOTEPAD.0101A1C8
0101A15B  ^ 73 F6           JNB SHORT NOTEPAD.0101A153
0101A15D    33C9            XOR ECX,ECX
滚动鼠标,发现popad,F4到0101a1ed
代码:
...
0101A1E4    2B7C24 28       SUB EDI,DWORD PTR SS:[ESP+28]
0101A1E8    897C24 1C       MOV DWORD PTR SS:[ESP+1C],EDI
0101A1EC    61              POPAD
0101A1ED    C3              RETN
//分析,这个函数应该是把shell从资源中释放到内存中
retn+retn到这里,要进入shell部分了吧
代码:
00A00000    E8 00000000     CALL 00A00005//进跳转jmp,F7
00A00005    5B              POP EBX
00A00006    81EB 05000000   SUB EBX,5
00A0000C    8B7424 08       MOV ESI,DWORD PTR SS:[ESP+8]
00A00010    E8 B7020000     CALL 00A002CC//获取kernel32的基地址
继续
代码:
00A00015    8983 BF040000   MOV DWORD PTR DS:[EBX+4BF],EAX
00A0001B    8B83 BF040000   MOV EAX,DWORD PTR DS:[EBX+4BF]
00A00021    8DB3 12050000   LEA ESI,DWORD PTR DS:[EBX+512]
00A00027    E8 CE020000     CALL 00A002FA                                  ; F7跟进,发现是获取GetModuleHandleA的地址
00A0002C    8983 22050000   MOV DWORD PTR DS:[EBX+522],EAX               
00A00032    8B83 BF040000   MOV EAX,DWORD PTR DS:[EBX+4BF]
00A00038    8DB3 DE040000   LEA ESI,DWORD PTR DS:[EBX+4DE]
00A0003E    E8 B7020000     CALL 00A002FA   //获取LoadLibraryA的地址
00A00043    8983 EB040000   MOV DWORD PTR DS:[EBX+4EB],EAX
00A00049    8B83 BF040000   MOV EAX,DWORD PTR DS:[EBX+4BF]
00A0004F    8DB3 EF040000   LEA ESI,DWORD PTR DS:[EBX+4EF]
00A00055    E8 A0020000     CALL 00A002FA  //获取GetProcAddress的地址
00A0005A    8983 FE040000   MOV DWORD PTR DS:[EBX+4FE],EAX
00A00060    8B83 BF040000   MOV EAX,DWORD PTR DS:[EBX+4BF]
00A00066    8DB3 26050000   LEA ESI,DWORD PTR DS:[EBX+526]
00A0006C    E8 89020000     CALL 00A002FA //获取VirtualProtect的地址
...
小插曲,00A002FA函数分析如下:
代码:
...
00A0031B    2BF2            SUB ESI,EDX
00A0031D    8975 F8         MOV DWORD PTR SS:[EBP-8],ESI
00A00320    8B75 F4         MOV ESI,DWORD PTR SS:[EBP-C]
00A00323    0376 3C         ADD ESI,DWORD PTR DS:[ESI+3C]
00A00326    8B76 78         MOV ESI,DWORD PTR DS:[ESI+78]
00A00329    0375 F4         ADD ESI,DWORD PTR SS:[EBP-C]
00A0032C    8B5E 20         MOV EBX,DWORD PTR DS:[ESI+20]
00A0032F    035D F4         ADD EBX,DWORD PTR SS:[EBP-C]
//获取kernel32.dll的导出表
...
00A00334    56              PUSH ESI
00A00335    8B3B            MOV EDI,DWORD PTR DS:[EBX]
00A00337    037D F4         ADD EDI,DWORD PTR SS:[EBP-C]
00A0033A    8B75 F0         MOV ESI,DWORD PTR SS:[EBP-10]
00A0033D    8B4D F8         MOV ECX,DWORD PTR SS:[EBP-8]
00A00340    FC              CLD
00A00341    F3:A6           REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00A00343    75 03           JNZ SHORT 00A00348
00A00345    5E              POP ESI
00A00346    EB 0C           JMP SHORT 00A00354                             ; 找到了跳
00A00348    5E              POP ESI
00A00349    83C3 04         ADD EBX,4
00A0034C    42              INC EDX
00A0034D    3B56 18         CMP EDX,DWORD PTR DS:[ESI+18]
00A00350  ^ 72 E2           JB SHORT 00A00334                              ; 在导出表中根据name逐个比对指定的函数
00A00352    EB 22           JMP SHORT 00A00376
00A00354    2B5E 20         SUB EBX,DWORD PTR DS:[ESI+20]
00A00357    2B5D F4         SUB EBX,DWORD PTR SS:[EBP-C]
00A0035A    D1EB            SHR EBX,1
00A0035C    035E 24         ADD EBX,DWORD PTR DS:[ESI+24]
00A0035F    035D F4         ADD EBX,DWORD PTR SS:[EBP-C]
00A00362    0FB703          MOVZX EAX,WORD PTR DS:[EBX]
00A00365    C1E0 02         SHL EAX,2
00A00368    0346 1C         ADD EAX,DWORD PTR DS:[ESI+1C]
00A0036B    0345 F4         ADD EAX,DWORD PTR SS:[EBP-C]
00A0036E    8B00            MOV EAX,DWORD PTR DS:[EAX]
00A00370    0345 F4         ADD EAX,DWORD PTR SS:[EBP-C]
00A00373    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX
00A00376    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]                   ; 根据name到序号再到address,一系列运算得到指定函数的地址
00A00379    8B5D EC         MOV EBX,DWORD PTR SS:[EBP-14]
00A0037C    C9              LEAVE
继续吧,
代码:
...
00A0007E    FF93 EB040000   CALL DWORD PTR DS:[EBX+4EB]                    ; 调用LoadLibrary加载dll
00A00084    8983 62050000   MOV DWORD PTR DS:[EBX+562],EAX
00A0008A    8D93 02050000   LEA EDX,DWORD PTR DS:[EBX+502]
00A00090    52              PUSH EDX
00A00091    50              PUSH EAX
00A00092    FF93 FE040000   CALL DWORD PTR DS:[EBX+4FE]                    ; 调用GetProcAddress获取函数地址
00A00098    8983 0E050000   MOV DWORD PTR DS:[EBX+50E],EAX
00A0009E    8D93 52050000   LEA EDX,DWORD PTR DS:[EBX+552]
00A000A4    52              PUSH EDX
00A000A5    FFB3 62050000   PUSH DWORD PTR DS:[EBX+562]
00A000AB    FF93 FE040000   CALL DWORD PTR DS:[EBX+4FE]                    ; 调用GetProcAddress获取MessageBoxA地址,后面应该是西风说的“写了点东西进去”吧
00A000B1    8983 5A050000   MOV DWORD PTR DS:[EBX+55A],EAX
00A000B7    BA 1C060000     MOV EDX,61C
00A000BC    03D3            ADD EDX,EBX
00A000BE    52              PUSH EDX
00A000BF    6A 04           PUSH 4
00A000C1    6A 04           PUSH 4
00A000C3    8B93 BF040000   MOV EDX,DWORD PTR DS:[EBX+4BF]
00A000C9    83C2 1C         ADD EDX,1C
00A000CC    52              PUSH EDX
00A000CD    FF93 34050000   CALL DWORD PTR DS:[EBX+534]                    ; 调用VirtualProtect
00A000D3    8B93 BF040000   MOV EDX,DWORD PTR DS:[EBX+4BF]
00A000D9    83C2 1C         ADD EDX,1C
00A000DC    891A            MOV DWORD PTR DS:[EDX],EBX
00A000DE    BA 20060000     MOV EDX,620
00A000E3    03D3            ADD EDX,EBX
00A000E5    52              PUSH EDX
00A000E6    FFB3 1C060000   PUSH DWORD PTR DS:[EBX+61C]
00A000EC    6A 04           PUSH 4
00A000EE    8B93 BF040000   MOV EDX,DWORD PTR DS:[EBX+4BF]
00A000F4    83C2 1C         ADD EDX,1C
00A000F7    52              PUSH EDX
00A000F8    FF93 34050000   CALL DWORD PTR DS:[EBX+534]
00A000FE    8B83 66050000   MOV EAX,DWORD PTR DS:[EBX+566]
00A00104    A9 02000000     TEST EAX,2
00A00109    74 04           JE SHORT 00A0010F
00A0010B    EB 04           JMP SHORT 00A00111
00A0010D    EB 02           JMP SHORT 00A00111
00A0010F    EB 18           JMP SHORT 00A00129
00A00111    6A 40           PUSH 40
00A00113    8D93 9D030000   LEA EDX,DWORD PTR DS:[EBX+39D]
00A00119    52              PUSH EDX
00A0011A    8D93 BF030000   LEA EDX,DWORD PTR DS:[EBX+3BF]
00A00120    52              PUSH EDX
00A00121    6A 00           PUSH 0
00A00123    FF93 0E050000   CALL DWORD PTR DS:[EBX+50E]                    ; 调用MessageBoxA,弹出作者的对话框;关掉继续单步
...
F8单步
代码:
...
00A001A0    5E              POP ESI
00A001A1    52              PUSH EDX
00A001A2    53              PUSH EBX
00A001A3    68 00800000     PUSH 8000
00A001A8    FF32            PUSH DWORD PTR DS:[EDX]
00A00179    6A 00           PUSH 0
00A0017B    FF93 76050000   CALL DWORD PTR DS:[EBX+576]                    ; VirtualAlloc,又申请内存干什么呢?
00A00181    8BF0            MOV ESI,EAX
00A00183    5B              POP EBX
00A00184    5A              POP EDX
00A00185    8B83 7E050000   MOV EAX,DWORD PTR DS:[EBX+57E]
00A0018B    0342 04         ADD EAX,DWORD PTR DS:[EDX+4]
00A0018E    8BF8            MOV EDI,EAX
00A00190    56              PUSH ESI
00A00191    57              PUSH EDI
00A00192    FF93 82050000   CALL DWORD PTR DS:[EBX+582]                    ; CALL NotePate.0101a145,刚开始调用此函数是把shell释放;F7跟进去,发现是解压.text区块,并备份到堆中
...
00A001BA  ^\75 B1           JNZ SHORT 00A0016D,这里又去申请内存,然后Call NotePate.0101a145去了。解压.rsrc区块


00A001C8   /E9 E7000000     JMP 00A002B4//要到恢复IAT了吗?分析如下:
代码:
00A001CD    53              PUSH EBX
00A001CE    56              PUSH ESI
00A001CF    8B46 0C         MOV EAX,DWORD PTR DS:[ESI+C]
00A001D2    0383 7E050000   ADD EAX,DWORD PTR DS:[EBX+57E]
00A001D8    50              PUSH EAX
00A001D9    FF93 72050000   CALL DWORD PTR DS:[EBX+572]          ; GetModuleHandleA,加载dll
00A001DF    0BC0            OR EAX,EAX
00A001E1    75 14           JNZ SHORT 00A001F7
00A001E3    5E              POP ESI
00A001E4    5B              POP EBX
00A001E5    53              PUSH EBX
00A001E6    56              PUSH ESI
00A001E7    8B46 0C         MOV EAX,DWORD PTR DS:[ESI+C]
00A001EA    0383 7E050000   ADD EAX,DWORD PTR DS:[EBX+57E]
00A001F0    50              PUSH EAX
00A001F1    FF93 6E050000   CALL DWORD PTR DS:[EBX+56E]
00A001F7    5E              POP ESI
00A001F8    5B              POP EBX
00A001F9    56              PUSH ESI
00A001FA    8BD0            MOV EDX,EAX
00A001FC    8B06            MOV EAX,DWORD PTR DS:[ESI]
00A001FE    8B7E 10         MOV EDI,DWORD PTR DS:[ESI+10]
00A00201    03BB 7E050000   ADD EDI,DWORD PTR DS:[EBX+57E]
00A00207    0BC0            OR EAX,EAX
00A00209    75 03           JNZ SHORT 00A0020E
00A0020B    8B46 10         MOV EAX,DWORD PTR DS:[ESI+10]
00A0020E    8BF0            MOV ESI,EAX
00A00210    03B3 7E050000   ADD ESI,DWORD PTR DS:[EBX+57E]
00A00216    E9 8C000000     JMP 00A002A7
00A0021B    F706 00000080   TEST DWORD PTR DS:[ESI],80000000     ; 判断是通过序数导入还是通过名称导入;为1时,序数导入
00A00221    74 1B           JE SHORT 00A0023E
00A00223    8B06            MOV EAX,DWORD PTR DS:[ESI]
00A00225    25 FFFFFF7F     AND EAX,7FFFFFFF
00A0022A    53              PUSH EBX
00A0022B    52              PUSH EDX
00A0022C    56              PUSH ESI
00A0022D    57              PUSH EDI
00A0022E    50              PUSH EAX
00A0022F    52              PUSH EDX
00A00230    FF93 6A050000   CALL DWORD PTR DS:[EBX+56A]          ; GetProAddress获取函数地址
00A00236    5F              POP EDI
00A00237    8907            MOV DWORD PTR DS:[EDI],EAX
00A00239    5E              POP ESI
00A0023A    5A              POP EDX
00A0023B    5B              POP EBX
00A0023C    EB 63           JMP SHORT 00A002A1
00A0023E    8B06            MOV EAX,DWORD PTR DS:[ESI]
00A00240    83C0 02         ADD EAX,2
00A00243    53              PUSH EBX
00A00244    52              PUSH EDX
00A00245    56              PUSH ESI
00A00246    57              PUSH EDI
00A00247    0383 7E050000   ADD EAX,DWORD PTR DS:[EBX+57E]
00A0024D    50              PUSH EAX
00A0024E    52              PUSH EDX
00A0024F    FF93 6A050000   CALL DWORD PTR DS:[EBX+56A]          ; GetProcAddress
00A00255    5F              POP EDI
00A00256    8B93 66050000   MOV EDX,DWORD PTR DS:[EBX+566]
00A0025C    A9 01000000     TEST EAX,1
00A00261    74 39           JE SHORT 00A0029C
00A00263    3B83 22050000   CMP EAX,DWORD PTR DS:[EBX+522]       ; 与GetModuleHandleA比较;后面分析知道,是的话就要加密这个Api的地址了
00A00269    EB 21           JMP SHORT 00A0028C                   ; 修改吧,不让他加密;这部分详细内容看看wzjok大虾的分析吧
00A0026B    8983 18060000   MOV DWORD PTR DS:[EBX+618],EAX
00A00271    8D93 3B060000   LEA EDX,DWORD PTR DS:[EBX+63B]
00A00277    C602 A1         MOV BYTE PTR DS:[EDX],0A1
00A0027A    B8 18060000     MOV EAX,618
00A0027F    03C3            ADD EAX,EBX
00A00281    8942 01         MOV DWORD PTR DS:[EDX+1],EAX
00A00284    66:C742 05 FFE0 MOV WORD PTR DS:[EDX+5],0E0FF
00A0028A    8BC2            MOV EAX,EDX
00A0028C    3B83 5A050000   CMP EAX,DWORD PTR DS:[EBX+55A]       ; 与user32.IsIconic地址比较,是就加密;同上
00A00292    EB 08           JMP SHORT 00A0029C
00A00294    8D93 47060000   LEA EDX,DWORD PTR DS:[EBX+647]
00A0029A    8BC2            MOV EAX,EDX
00A0029C    8907            MOV DWORD PTR DS:[EDI],EAX
00A0029E    5E              POP ESI
00A0029F    5A              POP EDX
00A002A0    5B              POP EBX
00A002A1    83C6 04         ADD ESI,4
00A002A4    83C7 04         ADD EDI,4
00A002A7    833E 00         CMP DWORD PTR DS:[ESI],0
00A002AA  ^ 0F85 6BFFFFFF   JNZ 00A0021B                         ; 获取函数地址的循环
00A002B0    5E              POP ESI
00A002B1    83C6 14         ADD ESI,14
00A002B4    837E 0C 00      CMP DWORD PTR DS:[ESI+C],0
00A002B8  ^ 0F85 0FFFFFFF   JNZ 00A001CD                         ; 加载dll的循环
00A002BE    8B83 04060000   MOV EAX,DWORD PTR DS:[EBX+604]
00A002C4    0383 7E050000   ADD EAX,DWORD PTR DS:[EBX+57E]
00A002CA    50              PUSH EAX
00A002CB    C3              RETN//终于到oep了
到了哈:
代码:
0100739D    6A 70           PUSH 70 // OEP
0100739F    68 98180001     PUSH NOTEPAD.01001898
010073A4    E8 BF010000     CALL NOTEPAD.01007568
010073A9    33DB            XOR EBX,EBX
010073AB    53              PUSH EBX
010073AC    8B3D CC100001   MOV EDI,DWORD PTR DS:[10010CC]       ; kernel32.GetModuleHandleA
010073B2    FFD7            CALL EDI
...
直接用od的“用ollydump脱壳调试进程”就可以了

小结:
1.把shell从资源释放出来;到堆中
2.把西风大虾的MessageBox弹起,;然后是解压缩各区块
3.填充IAT,加密kernel32.GetModuleHandleA和USER32.IsIconic两个API;
4.到oep

ps:新手学习,错误之处请指正;要睡觉了哇