Reminds me of my first program for DLL injection used for hacking Diablo II.
int EnumProcesses()
{
// reset the list box
SendDlgItemMessage(g_hwndDlg, IDC_LST_D2PROCESS, LB_RESETCONTENT, 0, 0);
int nCount = 0;
PROCESSENTRY32 ppe = {0};
ppe.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnapShot == INVALID_HANDLE_VALUE)
{
msgb("Error in CreateToolhelp32Snapshot");
return 0;
}
if(!Process32First(hSnapShot, &ppe))
{
msgb("Process32First returns FALSE.");
return 0;
}
while (Process32Next(hSnapShot, &ppe) && nCount < MAX_PROCESS )
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ppe.th32ProcessID);
char szBuf[256] = "";
HWND hwndTemp = GetHwndFromPid(ppe.th32ProcessID);
GetClassName(hwndTemp, szBuf, 255);
if (!strcmp(szBuf, "Diablo II"))
{
GetWindowText(hwndTemp, szBuf, sizeof(szBuf));
sprintf(g_szBuf, "%s (Pid: %d, Exe: %s)", szBuf, ppe.th32ProcessID, ppe.szExeFile);
SendDlgItemMessage(g_hwndDlg, IDC_LST_D2PROCESS, LB_ADDSTRING, 0, (LPARAM)(g_szBuf));
// update d2Process array
d2Process[nCount].hProcess = hProcess;
d2Process[nCount].dwPid = ppe.th32ProcessID;
strcpy(d2Process[nCount].szProcessName, ppe.szExeFile);
strcpy(d2Process[nCount].szMainWindowTitle, szBuf);
nCount++;
}
CloseHandle(hProcess);
}
CloseHandle(hSnapShot);
return nCount;
}
///////////////////////////////////////////////////////////
//
// Input: dwPid is the process id we want to inject our module
// szModuleName is the name of the module with full path
//
BOOL InjectModule(DWORD dwPid, char *szModuleName)
{
if (!dwPid || !szModuleName)
return FALSE;
int nIndex = 0;
PROCSTRUCT *pProcStruct = d2Process;
for (int j=0; j<MAX_D2PROCESS; j++)
{
if ( pProcStruct->dwPid == dwPid )
{
nIndex = j;
break;
}
pProcStruct++;
}
if(nIndex == MAX_D2PROCESS) // inavliad Pid in d2 process list
{
MessageBox(NULL, "Could not find a process matching the PID", "InjectModule Error", MB_OK);
return FALSE;
}
// get the process handle from pid
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if(!hProcess) // failed to open the process
{
char str[256];
sprintf(str, "Failed to open the process with Pid %l", dwPid);
MessageBox(NULL, str, "InjectModule Error", MB_OK);
return FALSE;
}
// reserve memory
LPVOID RemoteString = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(szModuleName), MEM_COMMIT, PAGE_READWRITE);
// write the path name
if( !WriteProcessMemory(hProcess, (LPVOID)RemoteString, (LPVOID)szModuleName, strlen(szModuleName), NULL) )
{
char str[256];
sprintf(str, "Failed to writes memory in the process with Pid %l", dwPid);
MessageBox(NULL, str, "InjectModule Error", MB_OK);
return FALSE;
}
// create remote thread passing address of LoadLibraryA
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0L,
(LPTHREAD_START_ROUTINE)(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"),
(LPVOID)RemoteString, 0L, NULL);
if(!hThread) // failed to create the thread
{
MessageBox(NULL, "Failed to create remote thread", "InjectModule Error", MB_OK);
return FALSE;
}
// get base address of our module and save it for cleanup
WaitForSingleObject(hThread, INFINITE);
DWORD hLoadedModule;
GetExitCodeThread(hThread, &hLoadedModule);
if (!hLoadedModule) // check if the module has been successfully loaded
{
sprintf(g_szBuf, "Failed to load %s", szModuleName);
MessageBox(NULL, g_szBuf, "Error", MB_OK);
return FALSE;
}
else
{
d2Process[nIndex].hLoadedModule = hLoadedModule; // update our modules base address
}
CloseHandle(hThread);
// free the momory
VirtualFreeEx(hProcess, (LPVOID)RemoteString, strlen(szModuleName), MEM_RELEASE);
CloseHandle(hProcess);
return TRUE;
}
BOOL EjectModule(DWORD dwPid)
{
if (!dwPid)
return FALSE;
int nIndex = 0;
PROCSTRUCT *pProcStruct = d2Process;
for (int j=0; j<MAX_D2PROCESS; j++)
{
if ( pProcStruct->dwPid == dwPid )
{
nIndex = j;
break;
}
pProcStruct++;
}
if(nIndex == MAX_D2PROCESS) // inavliad Pid in d2 process list
{
MessageBox(NULL, "Could not find a process matching the PID", "EjectModule Error", MB_OK);
return FALSE;
}
// get the process handle from pid
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if(!hProcess) // failed to open the process
{
char str[256];
sprintf(str, "Failed to open the process with Pid %l", dwPid);
MessageBox(NULL, str, "EjectModule Error", MB_OK);
return FALSE;
}
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0L,
(LPTHREAD_START_ROUTINE)(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "FreeLibrary"),
(LPVOID)d2Process[nIndex].hLoadedModule, 0L, NULL);
if(!hThread) // failed to create the thread
{
MessageBox(NULL, "Failed to create remote thread", "EjectModule Error", MB_OK);
return FALSE;
}
CloseHandle(hThread);
return TRUE;
}
////////////////////////////////////////////////////////////////
// get pid from the list string
//
long GetPidFromString(char *szListItem, char* szSearch, char chSep)
{
if(!szListItem || !szSearch || !strlen(szSearch)
|| !strlen(szListItem) || !chSep)
return -1;
char *pTemp = strstr(szListItem, szSearch);
if(!pTemp) // did not find the sub string szSearch
return -1;
pTemp += strlen(szSearch);
pTemp = substrchr(pTemp, chSep);
if(!pTemp) // did not find chSep
return -1;
return atol(pTemp);
}
////////////////////////////////////////////////////////////////
// callback function (called by EnumWindows)
// used to find the mapping between PID and application top app window.
//
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
ENUMWINDOWSTRUCT *pParam =(ENUMWINDOWSTRUCT *) lParam;
DWORD dwPID;
GetWindowThreadProcessId(hwnd, &dwPID);
if (dwPID == pParam->dwPID)
{
pParam->hwndRet = hwnd;
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////
// input: The process ID
// return: HWND of top app window with the argument PID
//
HWND GetHwndFromPid(DWORD dwPid)
{
ENUMWINDOWSTRUCT str(dwPid);
EnumWindows(EnumWindowsProc, (LPARAM)&str);
return str.hwndRet;
}
[此贴子已经被作者于2007-8-29 16:53:35编辑过]