shellcode流程

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,""
"");
		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参数






原文地址:https://www.cnblogs.com/hgy413/p/3693353.html