Hannock Posted May 14, 2017 Report Posted May 14, 2017 (edited) Hey everyone, I am not from Romania , forgive my English. i have a Question i want to ask. I have Written a PE Injector, judging from zwclose source(credits to him) in C, now i want to inject a simple Messagebox into a C++ application i created as well. it shows error 87 even when the application is open. Started to wonder what the problem was. My source code looks like this #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <tlhelp32.h> DWORD WINAPI ThreadProc() { MessageBoxA(NULL, "I am a Test MessageBox", "Message", MB_OK); return 0; } BOOL SetDebugPriviledge(BOOL State) { HANDLE hToken; TOKEN_PRIVILEGES tp; DWORD dwSize; ZeroMemory(&tp, sizeof(tp)); tp.PrivilegeCount = 1; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) { return FALSE; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) { CloseHandle(hToken); } if (State) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED; } if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, &dwSize)) { CloseHandle(hToken); } return CloseHandle(hToken); } DWORD GetProcessID(IN PCHAR szExeName) { DWORD dwRet = 0; DWORD dwCount = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot != INVALID_HANDLE_VALUE) { PROCESSENTRY32 pe = { 0 }; pe.dwSize = sizeof(PROCESSENTRY32); BOOL bRet = Process32First(hSnapshot, &pe); while (bRet) { if (!_stricmp(pe.szExeFile, szExeName)) { dwCount++; dwRet = pe.th32ProcessID; } bRet = Process32Next(hSnapshot, &pe); } CloseHandle(hSnapshot); } return dwRet; } void InjectFF() { SetDebugPriviledge(TRUE); PIMAGE_DOS_HEADER pIDH; PIMAGE_NT_HEADERS pINH; PIMAGE_BASE_RELOCATION pIBR; HANDLE hProcess, hThread; PUSHORT TypeOffset; PVOID ImageBase, Buffer, mem; ULONG i, Count, Delta, *p; hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, GetProcessID("hannock.exe")); if (!hProcess) { printf("\nError: Unable to open target process (%u)\n", GetLastError()); return -1; getchar(); } ImageBase = GetModuleHandle(NULL); pIDH = (PIMAGE_DOS_HEADER)ImageBase; pINH = (PIMAGE_NT_HEADERS)((PUCHAR)ImageBase + pIDH->e_lfanew); mem = VirtualAllocEx(hProcess, NULL, pINH->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (!mem) { printf("\nError: Unable to allocate memory in target process (%u)\n", GetLastError()); CloseHandle(hProcess); getchar(); return 0; } Buffer = VirtualAlloc(NULL, pINH->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); memcpy(Buffer, ImageBase, pINH->OptionalHeader.SizeOfImage); pIBR = (PIMAGE_BASE_RELOCATION)((PUCHAR)Buffer + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); Delta = (ULONG)mem - (ULONG)ImageBase; while (pIBR->VirtualAddress) { if (pIBR->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) { Count = (pIBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); TypeOffset = (PUSHORT)(pIBR + 1); for (i = 0; i<Count; i++) { if (TypeOffset[i]) { p = (PULONG)((PUCHAR)Buffer + pIBR->VirtualAddress + (TypeOffset[i] & 0xFFF)); *p += Delta; } } } pIBR = (PIMAGE_BASE_RELOCATION)((PUCHAR)pIBR + pIBR->SizeOfBlock); } if (!WriteProcessMemory(hProcess, mem, Buffer, pINH->OptionalHeader.SizeOfImage, NULL)) { printf("\nError: Unable to write process memory (%u)\n", GetLastError()); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); CloseHandle(hProcess); getchar(); return -1; } VirtualFree(Buffer, 0, MEM_RELEASE); hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((PUCHAR)ThreadProc + Delta), NULL, 0, NULL); if (!hThread) { printf("\nError: Unable to create thread in target process (%u)\n", GetLastError()); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; getchar(); } WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); CloseHandle(hProcess); } int main() { InjectFF(); return 0; } What am I not getting clearly? Edited May 14, 2017 by Hannock 2 Quote
u0m3 Posted May 14, 2017 Report Posted May 14, 2017 (edited) 39 minutes ago, Hannock said: [...] it shows error 87 [...] Can you be more specific? Where, during the execution, does it encounter this error? Also in SetDebugPriviledge, your call to AdjustTokenPrivileges is off: it should be AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) as per https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202(v=vs.85).aspx and https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619(v=vs.85).aspx (casting is optional). Try adding some break-points or debug statements to check the variables or return codes. Edited May 14, 2017 by u0m3 Clarifications 2 Quote
Hannock Posted May 14, 2017 Author Report Posted May 14, 2017 46 minutes ago, u0m3 said: Can you be more specific? Where, during the execution, does it encounter this error? Also in SetDebugPriviledge, your call to AdjustTokenPrivileges is off: it should be AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) as per https://msdn.microsoft.com/en-us/library/windows/desktop/aa375202(v=vs.85).aspx and https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619(v=vs.85).aspx (casting is optional). Try adding some break-points or debug statements to check the variables or return codes. Made the adjustments and still the same. it returns something like this Error: Unable to open target process (87) Quote
u0m3 Posted May 14, 2017 Report Posted May 14, 2017 Error code 87 is invalid parameter ERROR_INVALID_PARAMETER 87 (0x57) The parameter is incorrect. https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx When dealing with GetLastError this is helpful https://msdn.microsoft.com/en-us/library/windows/desktop/ms680582(v=vs.85).aspx. Just keep in mind it uses some fancy macro tricks to abstract the use of char vs wchar_t for storing strings. In your case, if you don't just use the code (which will use MessageBox to display the error) you should substitute the macro stuff so the resulting string can be used with printf (or alternatively use _tprintf which uses the same abstraction). Now regarding the cause of the error: my first suspect is GetProcessID; you never check if it returns a valid value. Second on the list is the flag PROCESS_CREATE_THREAD as it is restricted: Quote The following specific access rights are not allowed from a process to a protected process: [...] PROCESS_CREATE_THREAD [...] as specified https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx (bottom of page). You never specified what operating system you are using, so if you are using Windows Vista or above (which is quite probable) you should try to run the injector as administrator (if you are not doing that already). Quote
Hannock Posted May 14, 2017 Author Report Posted May 14, 2017 See what happened here. I open Processhacker and i check from the ProcessID and it injects successfully, suppose i close it and re inject , it fails again. I figured it should be from the GetProcessID Function. My Code Looks like this now. #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <tlhelp32.h> void InjectFF(); DWORD WINAPI ThreadProc() { MessageBoxA(NULL, "Hi From Injected Code", "Message", MB_OK); return 0; } BOOL SetDebugPriviledge(BOOL State) { HANDLE hToken; TOKEN_PRIVILEGES tp; DWORD dwSize; ZeroMemory(&tp, sizeof(tp)); tp.PrivilegeCount = 1; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) { return FALSE; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) { CloseHandle(hToken); } if (State) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED; } if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { CloseHandle(hToken); } return CloseHandle(hToken); } DWORD GetProcessID(IN PCHAR szExeName) { DWORD dwRet = 0; DWORD dwCount = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot != INVALID_HANDLE_VALUE) { PROCESSENTRY32 pe = { 0 }; pe.dwSize = sizeof(PROCESSENTRY32); BOOL bRet = Process32First(hSnapshot, &pe); while (bRet) { if (!_stricmp(pe.szExeFile, szExeName)) { dwCount++; dwRet = pe.th32ProcessID; InjectFF(); } bRet = Process32Next(hSnapshot, &pe); } CloseHandle(hSnapshot); } return dwRet; } void InjectFF() { PIMAGE_DOS_HEADER pIDH; PIMAGE_NT_HEADERS pINH; PIMAGE_BASE_RELOCATION pIBR; HANDLE hProcess, hThread; PUSHORT TypeOffset; PVOID ImageBase, Buffer, mem; ULONG i, Count, Delta, *p; hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE,5908); if (!hProcess) { printf("\nError: Unable to open target process (%u)\n", GetLastError()); return -1; getchar(); } ImageBase = GetModuleHandle(NULL); pIDH = (PIMAGE_DOS_HEADER)ImageBase; pINH = (PIMAGE_NT_HEADERS)((PUCHAR)ImageBase + pIDH->e_lfanew); mem = VirtualAllocEx(hProcess, NULL, pINH->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (!mem) { printf("\nError: Unable to allocate memory in target process (%u)\n", GetLastError()); CloseHandle(hProcess); getchar(); return 0; } Buffer = VirtualAlloc(NULL, pINH->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); memcpy(Buffer, ImageBase, pINH->OptionalHeader.SizeOfImage); pIBR = (PIMAGE_BASE_RELOCATION)((PUCHAR)Buffer + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); Delta = (ULONG)mem - (ULONG)ImageBase; while (pIBR->VirtualAddress) { if (pIBR->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) { Count = (pIBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); TypeOffset = (PUSHORT)(pIBR + 1); for (i = 0; i<Count; i++) { if (TypeOffset[i]) { p = (PULONG)((PUCHAR)Buffer + pIBR->VirtualAddress + (TypeOffset[i] & 0xFFF)); *p += Delta; } } } pIBR = (PIMAGE_BASE_RELOCATION)((PUCHAR)pIBR + pIBR->SizeOfBlock); } if (!WriteProcessMemory(hProcess, mem, Buffer, pINH->OptionalHeader.SizeOfImage, NULL)) { printf("\nError: Unable to write process memory (%u)\n", GetLastError()); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); CloseHandle(hProcess); getchar(); return -1; } VirtualFree(Buffer, 0, MEM_RELEASE); hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((PUCHAR)ThreadProc + Delta), NULL, 0, NULL); if (!hThread) { printf("\nError: Unable to create thread in target process (%u)\n", GetLastError()); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; getchar(); } WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE); CloseHandle(hProcess); } int main() { SetDebugPriviledge(TRUE); InjectFF(); return 0; } Where 5908 is the Process ID when i looked it up from Process Hacker. Quote
Hannock Posted May 14, 2017 Author Report Posted May 14, 2017 Ok, Many thanks Everyone. I finally Solved the Problem, it was with the ProcessID. Its solved now. Thanks everyone. Quote