[ASM][C++] Podmiana instrukcji call działającego procesu

0

W pamięci pewnego procesu pod adresem 0x004021DC mam wywołanie funkcji pod adresem 0x0050B4A0 z przekazaniem parametrów:
call sub_50B4A0

Chciałbym zamiast jej wywołać moją funkcje parametry wyświetlić i z powrotem przekazać parametry do oryginalnej funkcji by ta je obsłużyła jak gdyby nic. ;)

Taki myk:

DWORD pToCall = 0x004021DC; // oryginalny call
DWORD pOrigFunc = 0x0050B4A0; // oryginalny pointer do funkcji wywolywanej przez call


// moja funkcja podrobiona
int MyFunc(BYTE type,LPCSTR format,...) 
{ 
          
    printf("type: %x format: %s", type, format); 
     
       
   // tutaj jakos trzeba te parametry z powrotem przekazac do 
   // pOrigFunc
} 

DWORD pfunc = &MyFunc; 

// funkcja z nowa trescia calla
int __declspec(naked) ASMCallSnippet()
{
	_asm 
	{ 
	    call    pfunc    
	}
}


// napewno tresc funkcji ASMCallSnippet trzeba do memcpy przekazac troche inaczej ;D
memcpy((void*)pToCall, ASMCallSnippet, 5);
 

Nie mam pojęcia jak w mojej funkcji z powrotem wywołać oryginalną funkcje i przekzać jej oryginalne parametry.
Nie wiem, takze jak wstawić treść nowego calla (tj. ASMCallSnippet) do pamięci oryginalnego procesu.
Proszę o pomoc.

EDIT.
Próbowałem w ten sposób, ale niestety jest on wykrywany przez rootkita, który chroni proces :/

#define INST_NOP 0x90
#define INST_CALL 0xe8
#define INST_JMP 0xe9
#define INST_BYTE 0x00
#define SHORT_JZ 0x74

DWORD Intercept(int instruction, DWORD lpSource, DWORD lpDest, int len)
{
	DWORD realtarget;
	LPBYTE buffer = new BYTE[len];

	memset(buffer,0x90,len); 

	if (instruction != INST_NOP && len >= 5)
	{
		buffer[(len-5)] = instruction;
		DWORD dwJMP = (DWORD)lpDest - (lpSource + 5 + (len-5));
		memcpy(&realtarget,(void*)(lpSource+1),4);
		realtarget = realtarget+lpSource+5;
		memcpy(buffer + 1 + (len-5),&dwJMP,4);
	}
	if (instruction == SHORT_JZ)
	{
		buffer[0]=instruction;
		buffer[1]=(BYTE)lpDest;
	}
	if (instruction == INST_BYTE)
	{
		buffer[0]=(BYTE)lpDest;
	}
	MemcpyEx((DWORD*)lpSource, (DWORD) buffer, len);
	delete[] buffer;
	return realtarget;
}


DWORD pToCall = 0x004021DC; 
DWORD pOrigFunc = 0x0050B4A0;

typedef int (*FuncType)(BYTE type,LPCSTR format);
FuncType pOrigFunc = FuncType(0x0050B4A0);

int MyFunc(BYTE type,LPCSTR format) 
{           
    printf("type: %x format: %s", type, format); 	

//	char* args;
//	va_start(args, format);
	
	return pOrigFunc(type,format);
}

FuncType pMyFunc = &MyFunc;


int __declspec(naked) ASMCallSnippet()
{
        _asm 
        { 
            call    pMyFunc
        }
}


void ASMHook()
{
		Intercept(INST_JMP,pToCall,(DWORD)&ASMCallSnippet,5);	
}
0

pierwszy bajt to E8, kolejne 4 to odleglosc funkcji od kolejnego nastepnej instrukcji po call.
czyli jesli call masz pod adresem 0, callujesz adres 0xFFFFFFFF to bedzie
e8 fa ff ff ff
to dziala w obie strone, zawsze odejmujesz, najwyzszy bit oznacza kierunek.

bierzesz twoja funkcje, odejmujesz od jej adresu adres nastepnej instrukcji po callu, podmieniasz 4 bajty.
na koncu twojej funkcji skaczesz (jmp) do odpowiedniego adresu na ktory wskazywal odpowiedni call. Tak, musisz go rowniez obliczyc (i jmpa tez)

1 użytkowników online, w tym zalogowanych: 0, gości: 1