I am trying to inject a simple dll that creates a MessageBox in the target process. Using a injector from the www works without any issues. However using my own code to inject does not do anything at all (I am using it on notepad.exe)
I compiled both dll and this code as x64 debug in VS2017. Injector is created as Win32 console project.
All the stages in the code passes. I get a handle to the process and also the thread handle is valid. However the GetExitCode returns 0 so it fails all the time but I do not know why?
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (process == NULL)
{
std::cout << "Error opening process." << std::endl;
return false;
}
const char * dllString = "C:\\test.dll";
// load memory for dll
int bytes = sizeof(dllString);
PVOID mem = VirtualAllocEx(process, NULL, sizeof(dllString) + 1, MEM_COMMIT, PAGE_READWRITE);
if (mem == NULL)
{
std::cout << "Unable to allocate mem." << std::endl;
CloseHandle(process);
return false;
}
// write dll path to that location
SIZE_T bytesWritten;
BOOL status = WriteProcessMemory(process, mem, dllString, sizeof(dllString) + 1, &bytesWritten);
if (!status)
{
std::cout << "Writing dll path failed." << std::endl;
VirtualFreeEx(process, mem, sizeof(dllString) + 1, MEM_RELEASE);
CloseHandle(process);
return false;
}
FARPROC loadLibrary = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
HANDLE thread = CreateRemoteThread(process, NULL, NULL, reinterpret_cast<LPTHREAD_START_ROUTINE>(loadLibrary), mem, NULL, NULL);
if (thread == INVALID_HANDLE_VALUE)
{
std::cout << "Unable to create thread in remote process. " << std::endl;
VirtualFreeEx(process, mem, sizeof(dllString) + 1, MEM_RELEASE);
CloseHandle(process);
}
WaitForSingleObject(thread, INFINITE);
DWORD exitCode = 0;
GetExitCodeThread(thread, &exitCode);
if (exitCode != 0)
std::cout << "DLL loaded successfully." << std::endl;
else
std::cout << "DLL loading failed." << std::endl;
CloseHandle(thread);
VirtualFreeEx(process, mem, sizeof(dllString) + 1, MEM_RELEASE);
CloseHandle(process);
return true;
Just solved it myself. Actually a noob issue. sizeof in fact is returning the size of the pointer with is 64bits for x64 and not the length of the string for the memory I needed to allocate. So after changing it to strlen it worked.
Related
I have written DLL injector, to inject i use NtCreateThread to create remote thread into remote process
I work on 64 bit OS - Windows 7
To comiple i use
32 bit - g++ (tdm-2) 4.8.1
64 bit - g++ (tdm64-1) 5.1.0
Problem concerns 64 bit verion of my injector
I have 2 problems
1)
OK. My injector sometimes work and sometimes not work.
I dont know what is reason.
This is problematic line
funcNtCreateThreadEx( &hRemoteThread,GENERIC_EXECUTE, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, (LPVOID)ntbuffer );
When i call function NtCreateThreadEx and in last argument is pointer to NtCreateThreadExBuffer, it not work.
funcNtCreateThreadEx( &hRemoteThread,GENERIC_EXECUTE /*GENERIC_ALL 0x1FFFFF/*Może tu jest błąd*/, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, **ntbuffer** );
When i give in last parametr NULL it works and I DONT KNOW WHY.
funcNtCreateThreadEx( &hRemoteThread,GENERIC_EXECUTE /*GENERIC_ALL 0x1FFFFF/*Może tu jest błąd*/, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, **NULL** );
Any idea?
2)
I use NtCreateThreadEx because i want inject code to SYSTEM PROCESS (like csrss.exe) because i like BSoD :).
Unfortunately, my injector can inject code ONLY to process in this same session.
Reason is ?Session Separation? (implemented on Vista and every later OS)
It is rise why i cannot use CreateRemoteThread
I have thought when i use NtCreateThreadEx separation of sessions is not a problem.
I try inject DLL to process in sesion 0.
I tried reduce the privileges
I replaced:
HProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
on
HProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, PID);
etc. but it not work.
Can you tell me why NtCreateThreadEx() works in admin mode, but not in standard mode ?
Maby i should use other undocumented functions (like NtCreateThreadEx) for example NtOpenProcess to get handle to process with all access?
I need any idea what i should doing. Please help me.
#include <iostream>
#include <string>
#include <windows.h>
struct NtCreateThreadExBuffer;
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress, LPVOID lpSpace);
BOOL EnableDebugPrivilege();
int main()
{
int PIDOfProcess = 0;
std::string pathToDLL = "dll64.dll\0"; ///find DLL in local directory
DWORD PID = (DWORD)PIDOfProcess; ///PID
HANDLE HProcess = NULL; ///Handle to process
LPVOID LibAddr = NULL; ///Address of procedure 'LoadLibraryA'
LPVOID DllAdr = NULL; ///Address of memory in other process
HANDLE hThread = NULL; ///Handle to remote thread
int WirteStatus = 0; ///Status of writing to memory of other process
std::cout << "Get PID of process" << std::endl;
std::cin >> PIDOfProcess;
PID = (DWORD)PIDOfProcess;
if(EnableDebugPrivilege() == true)
{
std::cout << "Debug privilege was enabled with status: "<< GetLastError() << " [OK]" << std::endl;
}else std::cout << "Debug privilege was not enabled: "<< GetLastError() << " [FAILED]" << std::endl;
/*
NtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId );*/
/// NtOpenProcess();
HProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, PID);
if(HProcess == NULL)
{
std::cout << "Could not find process: "<< GetLastError() << " [FAILED]" << std::endl;
system("pause");
return GetLastError();
} std::cout << "Process opened: [OK]" << std::endl;
DllAdr = (LPVOID)VirtualAllocEx(HProcess, NULL, pathToDLL.size() +1, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(DllAdr == NULL)
{
std::cout << "Cannot allocate memory in remote process: "<< GetLastError() << " [FAILED]" << std::endl;
system("pause");
return GetLastError();
} std::cout << "Region of memory in remote process allocated: [OK]" << std::endl;
WirteStatus = WriteProcessMemory(HProcess, (LPVOID)DllAdr, pathToDLL.c_str() ,pathToDLL.size()+1, NULL);
if(WirteStatus == 0)
{
std::cout << "Could not write to process's address space: "<< GetLastError() << " [FAILED]" << std::endl;
system("pause");
return GetLastError();
} std::cout << "A memory has written name of DLL: [OK]" << std::endl;
LibAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(LibAddr == NULL)
{
std::cout << "Unable to locate LoadLibraryA: "<< GetLastError() << " [FAILED]" << std::endl;
system("pause");
return GetLastError();
} std::cout << "A address of procedure LoadLibraryA has found [OK]" << std::endl;
hThread = NtCreateThreadEx(HProcess,LibAddr,DllAdr);
if(hThread == NULL)
{
std::cout << "Could not create remote thread on process: "<< GetLastError() << " [FAILED]" << std::endl;
system("pause");
return GetLastError();
}
system("pause");
}
struct NtCreateThreadExBuffer///This information is derived based on reverse engineering work.
{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpSpace)
{
///The prototype of NtCreateThreadEx from undocumented.ntinternals.com
///typ_zwracanej_wartości (__konwencja_wywolania*nazwa_wskaźnika)(typ1 argument1, typ2 argument2);
/* 2OOO, 11 November http://undocumented.ntinternals.net/
NTSYSAPI NTSTATUS NTAPI NtCreateThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId,
IN PCONTEXT ThreadContext,
IN PINITIAL_TEB InitialTeb,
IN BOOLEAN CreateSuspended );*/
typedef LONG64 (WINAPI * functypeNtCreateThreadEx)(
PHANDLE ThreadHandle, ///Handle to thread which will be created /// OUT
ACCESS_MASK DesiredAccess, ///possible: GENERIC_WRITE GENERIC_READ GENERIC_EXECUTE GENERIC_ALL//// IN
LPVOID ObjectAttributes, /// IN,OPTIONAL
HANDLE ProcessHandle, ///Handle to our process /// IN
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
/*DWORD*/LONG64 dwStackSize,
LONG64 SizeOfStackCommit,
LONG64 SizeOfStackReserve,
LPVOID lpBytesBuffer ///pointer to initialized object of NtCreateThreadExBuffer
);
NtCreateThreadExBuffer * ntbuffer = NULL;
HANDLE hRemoteThread = NULL;
HMODULE hNtDllModule = NULL;
functypeNtCreateThreadEx funcNtCreateThreadEx = NULL;
ntbuffer = new NtCreateThreadExBuffer;
memset (ntbuffer,0,sizeof(NtCreateThreadExBuffer));///fill buffer zeros
DWORD temp1 = 0;
DWORD temp2 = 0;
ntbuffer->Size = sizeof(NtCreateThreadExBuffer);
ntbuffer->Unknown1 = 0x10003;
ntbuffer->Unknown2 = 0x8;
ntbuffer->Unknown3 = &temp2;
ntbuffer->Unknown4 = 0;
ntbuffer->Unknown5 = 0x10004;
ntbuffer->Unknown6 = 4;
ntbuffer->Unknown7 = &temp1;
ntbuffer->Unknown8 = 0;
//Get handle for ntdll which contains NtCreateThreadEx
hNtDllModule = GetModuleHandle( "ntdll.dll" );
if ( hNtDllModule == NULL )
{
std::cout << "Cannot get module ntdll.dll error: " << GetLastError() << std::endl;
return NULL;
} std::cout << "A 'ntdll.dll' module has got: "<< GetLastError() << " [OK]" << std::endl;
funcNtCreateThreadEx = (functypeNtCreateThreadEx)GetProcAddress( hNtDllModule, "NtCreateThreadEx" );
if ( !funcNtCreateThreadEx )
{
std::cout << "Cannot get procedure address error: " << GetLastError() << std::endl;
return NULL;
} std::cout << "'NtCreateThreadEx' has executed: "<< GetLastError() << " [OK]" << std::endl;
///Here is problem - when in last argument i replace NULL
funcNtCreateThreadEx( &hRemoteThread,GENERIC_EXECUTE /*GENERIC_ALL 0x1FFFFF/*Może tu jest błąd*/, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, ntbuffer );
std::cout << "_______________________________________ " << std::endl;
std::cout << "NtCreateThreadEx' has status: " << GetLastError() << std::endl;
std::cout << "hRemoteThread: " << hRemoteThread << std::endl;
std::cout << "State of handle to DLL: " << hNtDllModule << std::endl;
std::cout << "Addres of prcoedure NtCreateThreadEx: " << funcNtCreateThreadEx << std::endl;
return hRemoteThread;
}
BOOL EnableDebugPrivilege()
{
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
{
return FALSE;
}
if(!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ))
{
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = luid;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges( hToken, false, &tkp, sizeof( tkp ), NULL, NULL ))
{
return FALSE;
}
if(!CloseHandle( hToken ))
{
return FALSE;
}
return TRUE;
}
try: zwcreatethreatex function.
typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdllDll, "ZwCreateThreadEx");
if (NULL == ZwCreateThreadEx)
{
ShowError("GetProcAddress_ZwCreateThread");
return FALSE;
}
I have written DLL injector. I used CreateRemoteThread to inject my DLL to process and all was good.
Now i am trying inject DLL to process by undocumented function - NtCreateThreadEx. I have written injector but he is not working.
When i use 32 bit injector to inject 32 bit DLL to 32 bit process
all working good.
Problem is when i use 64 bit injector to inject 64 bit DLL to 64 bit process.
My DLL code:
#include <windows.h>
///Compilation with option -m64
extern "C" BOOL __stdcall DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
MessageBox( NULL, "MESSAGE FROM 64 BIT DLL", "Lorem ipsum", MB_ICONINFORMATION | MB_OKCANCEL );
return 0;
}
My TestApp code
#include <iostream>
#include <windows.h>
int main()
{
std::cout << " Lorem IPSUM" << std::endl;
//HMODULE HDLL = LoadLibraryA("dll64.dll");
//std::cout << "Error: " << GetLastError() << std::endl;
while(1)
{
std::cout << "petla" << std::endl;
Sleep(5000);
}
return 0;
}
My injector code:
#include <iostream>
#include <string>
#include <windows.h>
/// 64 bit OS - Windows 7
///=====================
///* In this same user context ("User")
///TYPE OF(32/64 bits)
///INJECTOR===DLL===PROCESS===RESULT
/// 32 32 32 -SUCESS
/// 64 64 64 -FALIED (error: 1300)
//Handle to process,Address of'LoadLibraryA',see DllAdr
///TO DO
///* Inject DLL to process from normal user context ("User") to higher user context (Zarzadca)
///* Inject DLL to process from normal user context ("User") to other normal user context (User1)
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress, LPVOID lpSpace);
int privileges();
int main()
{
int PIDOfProcess = 0;
std::string pathToDLL = "dll64.dll\0"; ///find DLL in local directory
DWORD PID = (DWORD)PIDOfProcess; ///PID
HANDLE HProcess = NULL; ///Handle to process
LPVOID LibAddr = NULL; ///Address of procedure 'LoadLibraryA'
LPVOID DllAdr = NULL; ///Address of memory in other process
HANDLE hThread = NULL; ///Handle to remote thread
int WirteStatus = 0; ///Status of writing to memory of other process
std::cout << "ptr size = " << sizeof(void *) << std::endl;
std::cout << "Get PID of process" << std::endl;
std::cin >> PIDOfProcess;
PID = (DWORD)PIDOfProcess;
///std::cout << "Get path to DLL" << std::endl;
///std::cin >> pathToDLL;
if( privileges() != 0 )
{
std::cout << "Cannot get the right privileges" << std::endl;
}
HProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if(HProcess == NULL)
{
std::cout << "Could not find process" << std::endl;
std::cout << GetLastError() << std::endl;
system("pause");
return GetLastError();
}
DllAdr = (LPVOID)VirtualAllocEx(HProcess, NULL, pathToDLL.size() +1, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(DllAdr == NULL)
{
std::cout <<"Can not allocate memory." << std::endl;
std::cout << GetLastError() << std::endl;
system("pause");
return GetLastError();
}
WirteStatus = WriteProcessMemory(HProcess, (LPVOID)DllAdr, pathToDLL.c_str() ,pathToDLL.size()+1, NULL);
if(WirteStatus == 0)
{
std::cout << "Could not write to process's address space" << std::endl;
std::cout << GetLastError() << std::endl;
system("pause");
return GetLastError();
}
LibAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(LibAddr == NULL)
{
std::cout << "Unable to locate LoadLibraryA" << std::endl;
std::cout << GetLastError() << std::endl;
system("pause");
return GetLastError();
}
hThread = NtCreateThreadEx(HProcess,LibAddr,DllAdr);
///DWORD threadId = 0;
///hThread = CreateRemoteThread(HProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LibAddr, DllAdr, 0, &threadId);
if(hThread == NULL)
{
std::cout << "Error: ";
std::cout << GetLastError() << std::endl;
system("pause");
return GetLastError();
}
system("pause");
}
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpSpace)
{
///The prototype of NtCreateThreadEx from undocumented.ntinternals.com
typedef DWORD (WINAPI * functypeNtCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD Unknown1,
DWORD Unknown2,
LPVOID Unknown3
);
HANDLE hRemoteThread = NULL;
HMODULE hNtDllModule = NULL;
functypeNtCreateThreadEx funcNtCreateThreadEx = NULL;
//Get handle for ntdll which contains NtCreateThreadEx
hNtDllModule = GetModuleHandle( "ntdll.dll" );
if ( hNtDllModule == NULL )
{
std::cout << "Cannot get module ntdll.dll error: " << GetLastError() << std::endl;
return NULL;
}
funcNtCreateThreadEx = (functypeNtCreateThreadEx)GetProcAddress( hNtDllModule, "NtCreateThreadEx" );
if ( !funcNtCreateThreadEx )
{
std::cout << "Cannot get procedure address error: " << GetLastError() << std::endl;
return NULL;
}
funcNtCreateThreadEx( &hRemoteThread, /*GENERIC_ALL*/0x1FFFFF, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, NULL );
std::cout << "Status NtCreateThreadEx " << GetLastError() << std::endl;
std::cout << "hRemoteThread: " << hRemoteThread << std::endl;
std::cout << "hNtDllModule: " << hNtDllModule << std::endl;
std::cout << "funcNtCreateThreadEx: " << funcNtCreateThreadEx << std::endl;
return hRemoteThread;
}
int privileges()
{
HANDLE Token;
TOKEN_PRIVILEGES tp;
if(OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token)) ///It opens the access token associated with a process.
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);///Function retrieves the locally unique identifier (LUID)
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(Token, false, &tp, sizeof(tp), NULL, NULL) != 0)///Function enables or disables privileges in the specified access token.
{
return 0; //OK
}
}
return 1;
}
When i use 64 bit injector to inject 64 bit DLL to 64 bit process, function NtCreateThreadEx return code of error 1300 and my DLL doesn't execute.
I use to compile on 64 bit architecture: g++ (tdm64-1) 5.1.0
I am working on Virus Windows 7 64 bit as normal user. Run as administrator doesn't help.
I dont know why it doesn't work, what i doing wrong.
PS: When i use 32 bit injector to inject 32 bit DLL to 32 bit process, function NtCreateThreadEx return code of error 1300 but my DLL execute.
In 32 bit version TestApp GetLastError return code 1114.
I use to compile on 32 bit architecture: g++ (tdm-2) 4.8.1
I include image
I based on:
http://www.p-programowanie.pl/cpp/dll-injection/ - Dll Injection (polish)
====
http://www.codeproject.com/Questions/369890/Ask-about-NtCreateThreadEx-in-Window-x
- Ask about NtCreateThreadEx in Window 7 x64!
=====
http://www.rohitab.com/discuss/topic/39535-code-injections-beginner-and-advanced/ Code Injections [beginner and advanced]
=====
http://securityxploded.com/ntcreatethreadex.php Remote Thread Execution in System Process using NtCreateThreadEx for Vista & Windows7
=====
http://cpp0x.pl/dokumentacja/WinAPI/Systemowe-kody-bledow-1300-1699/1470 Systemowe kody błędów (1300-1699) (polish)
Link to my topic on other forum (polish): http://forum.4programmers.net/C_i_C++/267735-dll_injection_w_windows_za_pomoca_nieudokumentowanej_funkcji_w_winapi?p=1234215#id1234215
My injector is working when i use him to inject DLL to other process in my user space (i am working as normal user)
but it is not working when
i am injecting to csrss.exe (or other system's process).
I get code of error 5 - Access Denied, when i run injector as Administrator i get code of error 0 (SUCCESS?) but my DLL not aborting process
( abort() - i try do BSoD).
I read about Session Separation and i think it is reason of my problem so i have one question: How i can hacking Windows :)
If it is imposibble can i inject DLL as normal user to proces in Administrator context (or other normal user's process) ?
I am learning making a memory patch using visual c++ on VS2015 & windows10. So I 'CreateProcess' with DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS.
Then I get CREATE_PROCESS_DEBUG_EVENT soon, where I write 0xcc to the point I wanna break. After that, the debug target just hanging there and 'WaitForDebugEvent' cannot get me any debug event.
I dump the target and the INT3 do exist as it should be, run the dump file and it execute as it should do.
Here is the code:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
HANDLE PatchProcess;
BYTE ReadBuffer[MAX_PATH] = { 0 };
BYTE int3Code[1] = { 0xcc };
BYTE dwOldStyle[4] = { 0x65,0x65,0x65,0x65 };
if (!CreateProcess(FILE_NAME, NULL, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
std::cout << "CreateProcess failed" << std::endl;
return false;
}
GetLastError();
PatchProcess = pi.hProcess;
DEBUG_EVENT dbEvent;
CONTEXT Regs;
DWORD dwState, Oldpp;
Regs.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
BOOL WhileDoFlag = true;
while (WhileDoFlag) {
WaitForDebugEvent(&dbEvent, INFINITE);
std::cout << "Waiting" << std::endl;
std::cout << "Debug event code:" << dbEvent.dwDebugEventCode << std::endl;
dwState = DBG_EXCEPTION_HANDLED;
switch (dbEvent.dwDebugEventCode)
{
case CREATE_PROCESS_DEBUG_EVENT:
ReadProcessMemory(pi.hProcess, (LPVOID)(BP), &ReadBuffer, 2, NULL);
GetLastError();
std::cout << "Code at" << BP << ":" << ReadBuffer[0] << std::endl;
system("pause");
VirtualProtectEx(pi.hProcess, (LPVOID)BP, 4, PAGE_EXECUTE_READWRITE, &Oldpp);
GetLastError();
WriteProcessMemory(pi.hProcess, (LPVOID)(BP), &int3Code, 2, NULL);
GetLastError();
dwState = DBG_CONTINUE;
break;
case EXIT_PROCESS_DEBUG_EVENT:
WhileDoFlag = false;
break;
case EXCEPTION_DEBUG_EVENT:
switch (dbEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
{
GetThreadContext(pi.hThread, &Regs);
if (Regs.Eip == BP + 1) {
Regs.Eip--;
WriteProcessMemory(pi.hProcess, (LPVOID)BP, &dwOldStyle, 4, 0);
GetLastError();
ReadProcessMemory(pi.hProcess, (LPVOID)(Regs.Ebp), &ReadBuffer, 1, 0);
GetLastError();
MessageBox(0, (char*)ReadBuffer, "patch test", MB_OK);
SetThreadContext(pi.hThread, &Regs);
}
dwState = DBG_CONTINUE;
break;
}
}
break;
}
ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, dwState);
}
Is it some kind of secure protection on Windows(after XP)?
PS:IDA can get the Breakpoint at the right place from the dump file with default local win32 debugger.
PS2:Using ollydbg to debug the dump file, the target crashed when execute
mov dword ptr ss:[esp+0x4],eax
eax is a ModuleEntryPoint
esp+0x4 is also a ModuleEntryPoint
Is it a bad breakpoint I add that caused the problem?
0xCC is one byte, you're writing 2 bytes causing the target process to crash, one of the bytes you're writing is just random garbage. Only write the one byte in your call to WriteProcessMemory()
In the following function, when I hit the FindVolumeClose() line, I always get the error outlined below. Any ideas why this happens?
Unhandled exception at 0x11000000 in BootFixFFS.exe: 0xC0000005: Access violation (parameters: 0x00000008).
char buffer[MAX_PATH];
HANDLE hVol = FindFirstVolume(buffer, MAX_PATH);
if (hVol == INVALID_HANDLE_VALUE) {
std::cout << "No volumes found\n.";
return FALSE;
}
std::string strVol = buffer;
strVol.pop_back();
HANDLE hPart = CreateFile(strVol.c_str(), 0, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hPart == INVALID_HANDLE_VALUE) {
FindVolumeClose(hVol);
std::cout << "Couldn't create file: " << GetLastError() << "\n";
return FALSE;
}
int numPartitions = 8;
DWORD dwDliSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + numPartitions * sizeof(PARTITION_INFORMATION_EX);
DRIVE_LAYOUT_INFORMATION_EX *dli = (DRIVE_LAYOUT_INFORMATION_EX*) new BYTE[dwDliSize];
DWORD dwSize;
ZeroMemory(&dli, sizeof(dli));
BOOL bSuccess = DeviceIoControl(hPart, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, &dli, dwDliSize, &dwSize, NULL);
CloseHandle(hPart);
FindVolumeClose(hVol);
if (bSuccess == FALSE) {
std::cout << "Couldn't get device information: " << GetLastError() << "\n";
return FALSE;
}
return TRUE;
It seems to me that ZeroMemory(&dli, sizeof(dli)) is not doing what you want it to do. It erases the address from dli, instead of zeroing the content of the byte array. Maybe ZeroMemory(dli, dwDliSize) is what you meant?
Also, the more serious error is using &dli when calling DeviceIoControl. You are basically overwriting your entire stack, and destroying the local variables.
I read a couple of posts on how to check if a process has exited from a different process (I realize some people get hung up on semantics here, but just humor me) and I tried to implement it but am running into the error code 5 ("ERROR_ACCESS_DENIED") all over the place.
Here is what I do.
1) Process 1 (P1) launches process 2 and writes to a shared memory location its own PID.
2) Process 2 (P2) reads the PID from shared memory
3) P2 calls OpenProcess(...) with P1's PID to save a handle that it can check later.
4) P2 calls GetExitCodeProcess(...) with P1's PID repeatedly and checks for a STILL_ACTIVE code.
In the above method, I keep getting the ACCESS_DENIED error on GetExitCodeProcess. I've tried modifying P2's privileges by using the below code from MSDN's docs:
HANDLE proc_h = OpenProcess(SYNCHRONIZE, FALSE, GetCurrentProcessId());
HANDLE hToken;
OpenProcessToken(proc_h, TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue(NULL, lpszPrivilege, &luid );
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Enable the privilege
AdjustTokenPrivileges(hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);
But I keep getting the ACCESS_DENIED error on the call to OpenProcessToken(...) method. So does this indicate some sort of system level hurdle? I do have admin rights on my machine and I'm running XP.
Thanks in advance for any help.
The handle passed to GetExitCodeProcess requires PROCESS_QUERY_INFORMATION access right.
The following works fine:
int main(int a_argc, char** a_argv)
{
int pid = atoi(*(a_argv + 1));
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (NULL != h)
{
Sleep(2000);
DWORD exit_code;
if (FALSE == GetExitCodeProcess(h, &exit_code))
{
std::cerr << "GetExitCodeProcess() failure: " <<
GetLastError() << "\n";
}
else if (STILL_ACTIVE == exit_code)
{
std::cout << "Still running\n";
}
else
{
std::cout << "exit code=" << exit_code << "\n";
}
}
else
{
std::cerr << "OpenProcess() failure: " << GetLastError() << "\n";
}
return 0;
}
Instead of polling on GetExitCodeProcess open the handle with SYNCHRONIZE and wait for it to exit:
int main(int a_argc, char** a_argv)
{
int pid = atoi(*(a_argv + 1));
HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid);
if (NULL != h)
{
WaitForSingleObject(h, 5000); // Change to 'INFINITE' wait if req'd
DWORD exit_code;
if (FALSE == GetExitCodeProcess(h, &exit_code))
{
std::cerr << "GetExitCodeProcess() failure: " <<
GetLastError() << "\n";
}
else if (STILL_ACTIVE == exit_code)
{
std::cout << "Still running\n";
}
else
{
std::cout << "exit code=" << exit_code << "\n";
}
}
else
{
std::cerr << "OpenProcess() failure: " << GetLastError() << "\n";
}
return 0;
}
OpenProcesstoken requires PROCESS_QUERY_INFORMATION you are opening the process with only SYNCHRONIZE access. See if you add | PROCESS_QUERY_INFORMATION if it works.
If you just want P2 to do something when P1 exits, there's another way that's probably rather easier: have P1 create a pipe and let P2 inherit a handle to that pipe. In P2, execute a read from the pipe. When P2's call to ReadFile returns with an error of ERROR_BROKEN_PIPE, P1 has exited.