能力值:
( LV7,RANK:100 )
|
-
-
10 楼
我写了一段测试汇编代码:
.386
.model flat, stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.data
shellcode db 0EBh, 42h, 8Bh, 59h, 3Ch, 8Bh, 5Ch, 0Bh, 78h, 03h, 0D9h, 8Bh, 73h, 20h, 03h, 0F1h
db 33h, 0FFh, 4Fh, 47h, 0ADh, 33h, 0EDh, 0Fh, 0B6h, 14h, 01h, 38h, 0F2h, 74h, 08h, 0C1h
db 0CDh, 03h, 03h, 0EAh, 40h, 0EBh, 0F0h, 3Bh, 6Ch, 24h, 04h, 75h, 0E6h, 8Bh, 73h, 24h
db 03h, 0F1h, 66h, 8Bh, 3Ch, 7Eh, 8Bh, 73h, 1Ch, 03h, 0F1h, 8Bh, 04h, 0BEh, 03h, 0C1h
db 5Bh, 5Fh, 53h, 0C3h, 0EBh, 4Fh, 33h, 0C0h, 64h, 33h, 40h, 30h, 8Bh, 40h, 0Ch, 8Bh
db 70h, 1Ch, 0ADh, 8Bh, 48h, 08h, 58h, 33h, 0DBh, 33h, 0FFh, 66h, 0BFh, 33h, 32h, 57h
db 68h, 75h, 73h, 65h, 72h, 8Bh, 0FCh, 53h, 51h, 53h, 50h, 50h, 53h, 57h, 68h, 54h
db 12h, 81h, 20h, 0E8h, 8Ah, 0FFh, 0FFh, 0FFh, 0FFh, 0D0h, 8Bh, 0C8h, 68h, 25h, 59h, 3Ah
db 0E4h, 0E8h, 7Ch, 0FFh, 0FFh, 0FFh, 0FFh, 0D0h, 59h, 68h, 97h, 19h, 6Ch, 2Dh, 0E8h, 6Fh
db 0FFh, 0FFh, 0FFh, 0FFh, 0D0h, 0E8h, 0ACh, 0FFh, 0FFh, 0FFh
db 'hello,world!', 0
.code
start:
mov eax, offset shellcode
call eax
invoke ExitProcess, 0
end start
|
能力值:
( LV7,RANK:100 )
|
-
-
11 楼
反汇编:
00401000 >/$ B8 00304000 MOV EAX,hellowor.00403000
00401005 |. FFD0 CALL EAX
00401007 |. 6A 00 PUSH 0 ; /ExitCode = 0
00401009 \. E8 00000000 CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
0040100E .-FF25 00204000 JMP DWORD PTR DS:[<&kernel32.ExitProcess>; kernel32.ExitProcess
=============================================
00403000 EB 42 JMP SHORT hellowor.00403044
00403002 8B59 3C MOV EBX,DWORD PTR DS:[ECX+3C]
00403005 8B5C0B 78 MOV EBX,DWORD PTR DS:[EBX+ECX+78]
00403009 03D9 ADD EBX,ECX
0040300B 8B73 20 MOV ESI,DWORD PTR DS:[EBX+20]
0040300E 03F1 ADD ESI,ECX
00403010 33FF XOR EDI,EDI
00403012 4F DEC EDI
00403013 47 INC EDI
00403014 AD LODS DWORD PTR DS:[ESI]
00403015 33ED XOR EBP,EBP
00403017 0FB61401 MOVZX EDX,BYTE PTR DS:[ECX+EAX]
0040301B 38F2 CMP DL,DH
0040301D 74 08 JE SHORT hellowor.00403027
0040301F C1CD 03 ROR EBP,3
00403022 03EA ADD EBP,EDX
00403024 40 INC EAX
00403025 ^EB F0 JMP SHORT hellowor.00403017
00403027 3B6C24 04 CMP EBP,DWORD PTR SS:[ESP+4]
0040302B ^75 E6 JNZ SHORT hellowor.00403013
0040302D 8B73 24 MOV ESI,DWORD PTR DS:[EBX+24]
00403030 03F1 ADD ESI,ECX
00403032 66:8B3C7E MOV DI,WORD PTR DS:[ESI+EDI*2]
00403036 8B73 1C MOV ESI,DWORD PTR DS:[EBX+1C]
00403039 03F1 ADD ESI,ECX
0040303B 8B04BE MOV EAX,DWORD PTR DS:[ESI+EDI*4]
0040303E 03C1 ADD EAX,ECX
00403040 5B POP EBX
00403041 5F POP EDI
00403042 53 PUSH EBX
00403043 C3 RETN
00403044 EB 4F JMP SHORT hellowor.00403095
00403046 33C0 XOR EAX,EAX
00403048 64:3340 30 XOR EAX,DWORD PTR FS:[EAX+30]
0040304C 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C]
0040304F 8B70 1C MOV ESI,DWORD PTR DS:[EAX+1C]
00403052 AD LODS DWORD PTR DS:[ESI]
00403053 8B48 08 MOV ECX,DWORD PTR DS:[EAX+8]
00403056 58 POP EAX
00403057 33DB XOR EBX,EBX
00403059 33FF XOR EDI,EDI
0040305B 66:BF 3332 MOV DI,3233
0040305F 57 PUSH EDI
00403060 68 75736572 PUSH 72657375
00403065 8BFC MOV EDI,ESP
00403067 53 PUSH EBX
00403068 51 PUSH ECX
00403069 53 PUSH EBX
0040306A 50 PUSH EAX
0040306B 50 PUSH EAX
0040306C 53 PUSH EBX
0040306D 57 PUSH EDI
0040306E 68 54128120 PUSH 20811254
00403073 E8 8AFFFFFF CALL hellowor.00403002
00403078 FFD0 CALL EAX
0040307A 8BC8 MOV ECX,EAX
0040307C 68 25593AE4 PUSH E43A5925
00403081 E8 7CFFFFFF CALL hellowor.00403002
00403086 FFD0 CALL EAX
00403088 59 POP ECX
00403089 68 97196C2D PUSH 2D6C1997
0040308E E8 6FFFFFFF CALL hellowor.00403002
00403093 FFD0 CALL EAX
00403095 E8 ACFFFFFF CALL hellowor.00403046
0040309A 68 656C6C6F PUSH 6F6C6C65
0040309F 2C 77 SUB AL,77
004030A1 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令
004030A2 72 6C JB SHORT hellowor.00403110
004030A4 64:2100 AND DWORD PTR FS:[EAX],EAX
可惜看不懂, 楼主不知道能否解释一下?
|
能力值:
( LV3,RANK:20 )
|
-
-
13 楼
00403000 EB 42 JMP SHORT hellowor.00403044 ;跳转到半中间
;-----------------------GetProcAddress ------------------
;ecx传递dll基址,堆栈传递hash值,返回值在eax中
00403002 8B59 3C MOV EBX,DWORD PTR DS:[ECX+3C]
00403005 8B5C0B 78 MOV EBX,DWORD PTR DS:[EBX+ECX+78]
00403009 03D9 ADD EBX,ECX
0040300B 8B73 20 MOV ESI,DWORD PTR DS:[EBX+20]
0040300E 03F1 ADD ESI,ECX
00403010 33FF XOR EDI,EDI
00403012 4F DEC EDI
00403013 47 INC EDI
00403014 AD LODS DWORD PTR DS:[ESI]
00403015 33ED XOR EBP,EBP
00403017 0FB61401 MOVZX EDX,BYTE PTR DS:[ECX+EAX]
0040301B 38F2 CMP DL,DH
0040301D 74 08 JE SHORT hellowor.00403027
0040301F C1CD 03 ROR EBP,3
00403022 03EA ADD EBP,EDX
00403024 40 INC EAX
00403025 ^EB F0 JMP SHORT hellowor.00403017
00403027 3B6C24 04 CMP EBP,DWORD PTR SS:[ESP+4]
0040302B ^75 E6 JNZ SHORT hellowor.00403013
0040302D 8B73 24 MOV ESI,DWORD PTR DS:[EBX+24]
00403030 03F1 ADD ESI,ECX
00403032 66:8B3C7E MOV DI,WORD PTR DS:[ESI+EDI*2]
00403036 8B73 1C MOV ESI,DWORD PTR DS:[EBX+1C]
00403039 03F1 ADD ESI,ECX
0040303B 8B04BE MOV EAX,DWORD PTR DS:[ESI+EDI*4]
0040303E 03C1 ADD EAX,ECX
00403040 5B POP EBX
00403041 5F POP EDI
00403042 53 PUSH EBX
00403043 C3 RETN
----------------------GetProcAddress结束--------------------------
半中间:
00403044 EB 4F JMP SHORT hellowor.00403095 ;跳到结尾
;------------------------------------------------------------------
真正开始处: ;由call跳回来的
00403046 33C0 XOR EAX,EAX
00403048 64:3340 30 XOR EAX,DWORD PTR FS:[EAX+30]
0040304C 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C]
0040304F 8B70 1C MOV ESI,DWORD PTR DS:[EAX+1C]
00403052 AD LODS DWORD PTR DS:[ESI]
00403053 8B48 08 MOV ECX,DWORD PTR DS:[EAX+8]
;以上几步取kernel32.dll基址,存到ecx中
;----------------------------构造堆栈------------------------------------
00403056 58 POP EAX ;对应结尾处的call,得到字符串地址
00403057 33DB XOR EBX,EBX
00403059 33FF XOR EDI,EDI
0040305B 66:BF 3332 MOV DI,3233
0040305F 57 PUSH EDI ; "32"
00403060 68 75736572 PUSH 72657375 ; "user"
00403065 8BFC MOV EDI,ESP ; edi->"user32"
00403067 53 PUSH EBX
00403068 51 PUSH ECX
00403069 53 PUSH EBX
0040306A 50 PUSH EAX
0040306B 50 PUSH EAX
0040306C 53 PUSH EBX
0040306D 57 PUSH EDI
;----------------------------完成堆栈------------------------------------
;此时,堆栈数据如下
; 0 ;ExitProcess参数
; base of kernel32.dll
; 0
; offset "hello"
; offset "hello"
; 0 ;MessageBoxA参数
; offset "user32"
0040306E 68 54128120 PUSH 20811254 ;LoadLiarbryA的hash值
00403073 E8 8AFFFFFF CALL hellowor.00403002 ;call自己写的GetProcAddress
00403078 FFD0 CALL EAX ;堆栈中已有参数"user32",直接LoadLiarbry
0040307A 8BC8 MOV ECX,EAX ;ecx->user32.dll
0040307C 68 25593AE4 PUSH E43A5925 ;hash of "MessageBoxA"
00403081 E8 7CFFFFFF CALL hellowor.00403002 ;自己的GetProcAddress
00403086 FFD0 CALL EAX ;MessageBoxA参数已提前构造好,直接call
00403088 59 POP ECX ;从堆栈中取kernel32基址
00403089 68 97196C2D PUSH 2D6C1997 ;hash of ExitProcess
0040308E E8 6FFFFFFF CALL hellowor.00403002 ;自己的GetProcAddress
00403093 FFD0 CALL EAX ;call ExitProcess
结尾:
00403095 E8 ACFFFFFF CALL hellowor.00403046 ;这里call主要是取"hello,world"的地址
;跳转到代码真正开始处
;------------------此处其实是ASCII串: "hello,world!"-------------------
0040309A 68 656C6C6F PUSH 6F6C6C65
0040309F 2C 77 SUB AL,77
004030A1 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令
004030A2 72 6C JB SHORT hellowor.00403110
004030A4 64:2100 AND DWORD PTR FS:[EAX],EAX
;----------------------字符串结束--------------------------------------
其实很简单,一开始连续两次jmp其实是避免机器码中出现0x00,因此用short jmp
jmp完成后call取字符串地址,并跳到真正的入口
入口处得到kernel32基址并构造堆栈,方便以后直接调用函数。(若以后再构造堆栈,就必须多次用清零操作,代码会变长)
然后就是不断得到函数地址并进行call
|