shellcode就是汇编的opcode,一般以子函数形式出现:
取得shellcode的方便方式是:
1.写一个函数如:
void __stdcall code(LONG &a,
LONG &b,
DWORD &c,
LONG &d,
DWORD &e)
取得它的汇编码:如:
push ebp
mov ebp,esp
sub esp,14h
push ebx
push esi
push edi
mov dword ptr [ebp-4],0FFFFFFFFh
mov dword ptr [ebp-0Ch],0
mov dword ptr [ebp-8],0
mov dword ptr [ebp-14h],0
mov dword ptr [ebp-10h],0
pushad
mov eax,22E4CCh
int 0FFh
mov dword ptr [ebp-4],eax
mov dword ptr [ebp-0Ch],ecx
mov dword ptr [ebp-14h],edx
mov dword ptr [ebp-8],esi
mov dword ptr [ebp-10h],edi
popad
mov eax,dword ptr [ebp+8]
mov ecx,dword ptr [ebp-4]
mov dword ptr [eax],ecx
mov edx,dword ptr [ebp+0Ch]
mov eax,dword ptr [ebp-0Ch]
mov dword ptr [edx],eax
mov ecx,dword ptr [ebp+10h]
mov edx,dword ptr [ebp-14h]
mov dword ptr [ecx],edx
mov eax,dword ptr [ebp+14h]
mov ecx,dword ptr [ebp-8]
mov dword ptr [eax],ecx
mov edx,dword ptr [ebp+18h]
mov eax,dword ptr [ebp-10h]
mov dword ptr [edx],eax
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 14h
转换成机器码:
unsigned char *asm_code()
{
__asm
{
lea eax,__code
jmp __ret
} // shellcode
__asm
{
__code://要加的汇编
//TODO
}
__asm nop//标志位,一般是int 3,即0xcc
__asm {__ret:}
}
int main()
{
unsigned char temp;
int i=1;
unsigned char* asm_p = asm_code();
FILE *fd = fopen("code.txt","w");
fprintf(fd,"unsigned char shellcode[] = \"");
while((temp = *asm_p) != 0x90)//标志位,一般是int 3,即0xcc
{
fprintf(fd,"\\x%.2x",temp);
asm_p ++;
if(i % 8 == 0) fprintf(fd,"\"\n\"");
i ++;
}
fprintf(fd,"\";");
fclose(fd);
运行得到shellcode[]数组在code.txt中,取出
调用方式一般采用:
#define QSHELLCODE {0x55, 0x8b, 0xec, 0xcd, 0xff, 0x5d, 0xc3}
#define SHELLCODE_SIZE 0x7
PVOID m_pShellCode = VirtualAlloc(NULL, SHELLCODE_SIZE, MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if (m_pShellCode)
{
byte ptr_shellcode[] = QSHELLCODE;
memcpy(m_pShellCode, ptr_shellcode,SHELLCODE_SIZE);
}
最后调用有两种方式,一种是:
pfn_Q pfn = (pfn_Q)m_ShellCode;
pfn(填参数);//函数直接调
另一种是汇编:
lea ecx, pfn
mov ecx, [ecx]
call ecx
当然,有参数就先push参数