#include <windows.h>
#include <stdio.h>






char x86_shellcode[]={
"\x6A\x00\x6A\xFF\xE8\x01\x00\x00\x00\xC3\xB8\x01\x01\x00\x00\xE8\x01\x00\x00\x00\xC3\x8B\xD4\x0F\x34\xC3"};
DWORD x86_shellcode_size=0x20;
DWORD x86_syscall_number_offset=0x0B;
/*
PUSH 0
PUSH -1
CALL TERM
RET
TERM:
MOV EAX,101h
CALL SYS
SYS:
MOV EDX,ESP
SYSENTER 
RET
*/


char wow64_shellcode[]={
"\x6A\x00\x6A\xFF\xE8\x01\x00\x00\x00\xC3\xB8\x01\x01\x00\x00\xE8\x03\x00\x00\x00\xC2\x08\x00\x01\x02\x03\x04\x05\x06\x07"};
DWORD wow64_shellcode_size=0x1E;
DWORD wow64_syscall_number_offset=0x0B;
DWORD wow64_call_offset=0x17;

/*
PUSH 0
PUSH -1
CALL TERM
RET
TERM:
MOV EAX,23h
CALL SYS
RETN 8
SYS:
JPM FAR X86SwitchTo64BitMode //Import from From FS:[0xC0]
*/




void KillApp(DWORD pid)
{

HMODULE h=GetModuleHandle("NTDLL.DLL");
FARPROC p=GetProcAddress(h,"ZwTerminateProcess");
char* code;
char type;
memcpy(&type,(char*)((char*)p+5),1);

/*
if type==0x64 that application is run in wow64 
else application is run under x86 environment

There is a difference between calling a syscall in x86 and x64 environment.

Important! If you run this code in VirtualBox (x86 environment), you need to change:

MOV EDX,ESP
SYSENTER 

to:

LEA EDX,[ESP+0x08]
INT 2E

VirtualBox doesn't have emulation for SYSENTER opcode
*/

int shellcode_size=0;
//Wow64
if(type==(char)0x64){
code=new char[wow64_shellcode_size];
memcpy(code,wow64_shellcode,wow64_shellcode_size);
memcpy((char*)(code+wow64_syscall_number_offset),(char*)((char*)p+1),4);
DWORD wow64_call_ptr;//get address of function which change mode to x64
__asm{
	MOV EAX,DWORD PTR FS:[0xC0]
	MOV wow64_call_ptr,EAX
}
memcpy((char*)(code+wow64_call_offset),(char*)((char*)wow64_call_ptr),7);
shellcode_size=wow64_shellcode_size;
}
//x86 app
else{
code=new char[x86_shellcode_size];
memcpy(code,x86_shellcode,x86_shellcode_size);
memcpy((char*)(code+x86_syscall_number_offset),(char*)((char*)p+1),4);
shellcode_size=x86_shellcode_size;
}






	HANDLE hProc=0;
	hProc=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_CREATE_THREAD, FALSE, pid);




 LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, shellcode_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 

    DWORD numBytesWritten;
    WriteProcessMemory(hProc, hRemoteMem, code, shellcode_size, &numBytesWritten);
 
   
    HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hRemoteMem, 0, 0, NULL);
 
        
    
CloseHandle(hProc);
}





int main(int argc,char** argv)
{

if(argc!=2)
{
	printf("usage: %s <pid>\n\n",argv[0]);
	return 0;
}
DWORD pid=atoi(argv[1]);
KillApp(pid);


return 0;
}