Hello I'm new to learning process injection, and having some trouble injecting a process with C++. I'm using CreateRemoteThread and WriteProcessMemory method. However I get Access violation executing location xxxx. the program breaks in my injected function with the said error. i checked through the disassembler and see a call that go to an invalid address, but i have no idea what's going on. i'm working with VS2019 on win10 64 bit, but the project build is x86. i've attached the screen shot of disassembler and error box, also below is my code. i will appreciate any assistant and help. thanks.
#include "stdafx.h"
//Declearations and structure defination
#if !defined INJCODE_H
#define INJCODE_H
int GetWindowTextRemoteA(HANDLE hProcess, HWND hWnd, LPSTR lpString);
int GetWindowTextRemoteW(HANDLE hProcess, HWND hWnd, LPWSTR lpString);
#ifdef UNICODE
#define GetWindowTextRemote GetWindowTextRemoteW
#else
#define GetWindowTextRemote GetWindowTextRemoteA
#endif // !UNICODE
#endif // !defined(INJCODE_H)
typedef LRESULT(WINAPI* SENDMESSAGE)(HWND, UINT, WPARAM, LPARAM);
typedef struct {
HWND hwnd;
SENDMESSAGE fnSendMessage; // pointer to user32!SendMessage
} INJDATA, * PINJDATA;
//---------------------------------------------------------------------
// ThreadFunc
// Notice: - the code being injected;
//it breaks in this function
static DWORD WINAPI ThreadFunc(INJDATA* pData)
{
int nXferred = 0; // number of chars retrieved by WM_GETTEXT
pData->fnSendMessage(pData->hwnd, WM_CLOSE, 0, 0);
return nXferred;
}
//---------------------------------------------------------------------
//Process injection routine
int GetTextRemote(HANDLE hProcess, HWND hWnd, BYTE* pbString, bool fUnicode)
{
HINSTANCE hUser32;
INJDATA* pDataRemote = 0; // the address (in the remote process) where INJDATA will be copied to;
DWORD* pCodeRemote = 0; // the address (in the remote process) where ThreadFunc will be copied to;
HANDLE hThread = NULL; // the handle to the thread executing the remote copy of ThreadFunc;
DWORD dwThreadId = 0;
int nCharsXferred = 0; // number of chars retrieved by WM_GETTEXT in the remote thread;
DWORD dwNumBytesXferred = 0; // number of bytes written/read to/from the remote process;
__try {
hUser32 = GetModuleHandle(__TEXT("user32"));
if (hUser32 == NULL)
__leave;
// Initialize INJDATA and then
// copy it to the remote process
INJDATA DataLocal = {
hWnd,
(SENDMESSAGE)GetProcAddress(hUser32, fUnicode ? "SendMessageW" : "SendMessageA")
};
if (DataLocal.fnSendMessage == NULL)
__leave;
// 1. Allocate memory in the remote process for INJDATA
// 2. Write a copy of DataLocal to the allocated memory
pDataRemote = (INJDATA*)VirtualAllocEx(hProcess, 0, sizeof(INJDATA), MEM_COMMIT, PAGE_READWRITE);
if (pDataRemote == NULL)
__leave;
//WriteProcessMemory( hProcess, pDataRemote, &DataLocal, sizeof(INJDATA), &dwNumBytesXferred );
if (WriteProcessMemory(hProcess, pDataRemote, &DataLocal, sizeof(INJDATA), &dwNumBytesXferred) == NULL) {
__leave;
}
// Calculate the number of bytes that ThreadFunc occupies
//const int cbCodeSize = ((LPBYTE) AfterThreadFunc - (LPBYTE) ThreadFunc);
const int cbCodeSize = 0x5d; // derectly used
pCodeRemote = (PDWORD)VirtualAllocEx(hProcess, 0, cbCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (pCodeRemote == NULL)
__leave;
if (WriteProcessMemory(hProcess, pCodeRemote, &ThreadFunc, cbCodeSize, &dwNumBytesXferred) == NULL) {
__leave;
}
// Start execution of remote ThreadFunc
hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pCodeRemote,
pDataRemote, 0, &dwThreadId);
if (hThread == NULL)
__leave;
WaitForSingleObject(hThread, INFINITE);
}
__finally {
if (pDataRemote != 0)
VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE);
if (pCodeRemote != 0)
VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
if (hThread != NULL) {
GetExitCodeThread(hThread, (PDWORD)&nCharsXferred);
CloseHandle(hThread);
}
}
return nCharsXferred;
}
//---------------------------------------------------------------------
//winProc to create win32 process
#define ID_TIMER 1
int GetWindowTextRemoteA(HANDLE hProcess, HWND hWnd, LPSTR lpString)
{
return GetTextRemote(hProcess, hWnd, (BYTE*)lpString, false);
}
int GetWindowTextRemoteW(HANDLE hProcess, HWND hWnd, LPWSTR lpString)
{
return GetTextRemote(hProcess, hWnd, (BYTE*)lpString, true);
}
TCHAR szAppName[] = TEXT("MenuDemo");
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int idColor[5] = { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH };
static int iSelection = IDM_BKGND_WHITE;
HMENU hMenu;
switch (message)
{
case WM_COMMAND:
hMenu = GetMenu(hwnd);
switch (LOWORD(wParam))
{
case IDM_FILE_NEW:
_TCHAR ch[128];
DWORD PID, TID;
TID = ::GetWindowThreadProcessId(hwnd, &PID);
if (PID) {
MessageBeep(MB_OK);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
GetWindowTextRemote(hProcess, hwnd, ch);
}
case IDM_FILE_OPEN:
case IDM_FILE_SAVE:
case IDM_FILE_SAVE_AS:
MessageBeep(0);
return 0;
case IDM_APP_EXIT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
return 0;
case IDM_EDIT_UNDO:
case IDM_EDIT_CUT:
case IDM_EDIT_COPY:
case IDM_EDIT_PASTE:
case IDM_EDIT_CLEAR:
MessageBeep(0);
return 0;
case IDM_BKGND_WHITE:
case IDM_BKGND_LTGRAY:
case IDM_BKGND_GRAY:
case IDM_BKGND_DKGRAY:
case IDM_BKGND_BLACK:
CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
iSelection = LOWORD(wParam);
CheckMenuItem(hMenu, iSelection, MF_CHECKED);
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)GetStockObject
(idColor[LOWORD(wParam) - IDM_BKGND_WHITE]));
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case IDM_TIMER_START:
if (SetTimer(hwnd, ID_TIMER, 1000, NULL))
{
EnableMenuItem(hMenu, IDM_TIMER_START, MF_GRAYED);
EnableMenuItem(hMenu, IDM_TIMER_STOP, MF_ENABLED);
}
return 0;
case IDM_TIMER_STOP:
KillTimer(hwnd, ID_TIMER);
EnableMenuItem(hMenu, IDM_TIMER_START, MF_ENABLED);
EnableMenuItem(hMenu, IDM_TIMER_STOP, MF_GRAYED);
return 0;
case IDM_APP_HELP:
MessageBox(hwnd, TEXT("Help not yet implemented!"), szAppName, MB_ICONEXCLAMATION | MB_OK);
return 0;
case IDM_APP_ABOUT:
MessageBox(hwnd, TEXT("Menu Demonstration Program\n") TEXT("(c) Charles Petzold, 1998"),
szAppName, MB_ICONINFORMATION | MB_OK);
return 0;
}
break;
case WM_TIMER:
MessageBeep(0);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
//---------------------------------------------------------------------
//main window procedure
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName,
TEXT("Menu Demonstration"),
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}