I get the error, "Debug Assertion Failed", when executing my .exe via the Start-Process command in PowerShell. I do not get this error when normally executing via File Explorer (double-click). Please see the error below.
There have been similar questions on this forum that have suggested I add the following code to mute the error:
#define NDEBUG
#include <assert.h>
While solving the error is best practice, I would like to know why the above doesn't work for me. For greater context, I am doing a DLL proxy.
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#define NDEBUG
#include <assert.h>
#define _CRT_SECURE_NO_DEPRECATE
#pragma warning (disable : 4996)
#pragma comment(linker, "/export:_nettle_aeads=tmpC652._nettle_aeads,#1")
DWORD WINAPI DoMagic(LPVOID lpParameter)
{
//https://stackoverflow.com/questions/14002954/c-programming-how-to-read-the-whole-file-contents-into-a-buffer
FILE* fp;
size_t size;
unsigned char* buffer;
fp = fopen("fz-dump-26072022-1635.bin", "rb");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
buffer = (unsigned char*)malloc(size);
//https://ired.team/offensive-security/code-injection-process-injection/loading-and-executing-shellcode-from-portable-executable-resources
fread(buffer, size, 1, fp);
void* exec = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, buffer, size);
((void(*) ())exec)();
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
HANDLE threadHandle;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// https://gist.github.com/securitytube/c956348435cc90b8e1f7
// Create a thread and close the handle as we do not want to use it to wait for it
threadHandle = CreateThread(NULL, 0, DoMagic, NULL, 0, NULL);
CloseHandle(threadHandle);
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
There are many more pragmas in the above code. Approx 400 more lines of similar export functions.
The solution is quite simple, adding the full path...
fp = fopen("C:\\Program Files\\FileZilla FTP Client\\fz-dump-26072022-1635.bin", "rb");
I found that the value of fp was NULL when executing via the PowerShell command Start-Process. This is because it was adding the file name fz-dump-26072022-1635.bin to the directory where PowerShell is called from, which is C:\Windows\System32\WindowsPowerShell\v1.0\. This explains why double clicking on the .exe works with no error, as the value of fp is correct, while calling it from any other directory doesn't work.
Related
I have two files, the file which I'll use to load the Dll into the process is the following:
#include <Windows.h>
int main()
{
// path to our dll
LPCSTR DllPath = any_path;
// Open a handle to target process
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 26188);
// Allocate memory for the dllpath in the target process
// length of the path string + null terminator
LPVOID pDllPath = VirtualAllocEx(hProcess, 0, strlen(DllPath) + 1,
MEM_COMMIT, PAGE_READWRITE);
// Write the path to the address of the memory we just allocated
// in the target process
WriteProcessMemory(hProcess, pDllPath, (LPVOID)DllPath,
strlen(DllPath) + 1, 0);
// Create a Remote Thread in the target process which
// calls LoadLibraryA as our dllpath as an argument -> program loads our dll
HANDLE hLoadThread = CreateRemoteThread(hProcess, 0, 0,
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32.dll"),
"LoadLibraryA"), pDllPath, 0, 0);
// Wait for the execution of our loader thread to finish
WaitForSingleObject(hLoadThread, INFINITE);
// Free the memory allocated for our dll path
VirtualFreeEx(hProcess, pDllPath, strlen(DllPath) + 1, MEM_RELEASE);
return 0;
}
So far, it's working properly and loading the Dll into the file, however, the Dll doesn't seem to be working:
#include "pch.h"
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>
DWORD WINAPI HackThread(HMODULE hModule)
{
//Create Console
AllocConsole();
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout);
std::cout << "ttt" << std::endl;
std::cin.get();
fclose(f);
FreeConsole();
FreeLibraryAndExitThread(hModule, 0);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)HackThread, hModule, 0, nullptr);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
I know the Dll is loading properly because the process is hitting the 'DLL_PROCESS_ATTACH' case and when I tested it with a message box instead of the CreateThread, it showed up, however, I can't seem to make the console show up. What would be the problem?
One issue I see is that your thread is re-mapping only stdout to the new console, but it is not re-mapping stdin as well. So it is quite likely (use a debugger to verify this) that std::cin.get() is failing and thus not blocking the thread from closing the console immediately after creating it.
I want to make a message box appear in notepad , so I found a simple dll injection example. The injector itself is not mine and seems to work fine (gets the process's id , creates a remote thread , gets absolute path of the dll file). The problem, I think, is in the implementation of the dll. The projects compile without any warnings, but the expected outcome isn't achieved. Can you take a look and help me understand the problem? (I have put the release version of the dll in the injector project folder)
dllmain.cpp:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "dll.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
DLLEXPORT void mess() {
MessageBoxA(NULL, "HELLO THERE", "From Notepad", NULL);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: mess(); break;
case DLL_THREAD_ATTACH: mess(); break;
case DLL_THREAD_DETACH: mess(); break;
case DLL_PROCESS_DETACH: mess(); break;
}
return TRUE;
}
dll.h:
#ifndef _DLL_H_
#define _DLL_H_
# define DLLEXPORT __declspec (dllexport)
# define DLLIMPORT __declspec (dllimport)
DLLEXPORT void mess(void);
#endif
and the injection.cpp for reference, it contains a function which finds the wanted process id, a function which creates the remote thread and a main:
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <conio.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define WIN32_LEAN_AND_MEAN
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
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 (!strcmp( szExeName, pe.szExeFile))
{
dwCount++;
dwRet = pe.th32ProcessID;
}
bRet = Process32Next(hSnapshot, &pe);
}
if (dwCount > 1)
dwRet = 0xFFFFFFFF;
CloseHandle(hSnapshot);
}
return dwRet;
}
BOOL CreateRemoteThreadInject(DWORD ID, const char * dll)
{
HANDLE Process;
LPVOID Memory;
LPVOID LoadLibrary;
if (!ID) return false;
Process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, ID);
LoadLibrary = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
Memory = (LPVOID)VirtualAllocEx(Process, NULL, strlen(dll) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Process, (LPVOID)Memory, dll, strlen(dll) + 1, NULL);
CreateRemoteThread(Process, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibrary, (LPVOID)Memory, NULL, NULL);
CloseHandle(Process);
VirtualFreeEx(Process, (LPVOID)Memory, 0, MEM_RELEASE);
return true;
}
int main()
{
char dll[MAX_PATH] ;
GetFullPathName("testdll.dll", MAX_PATH, dll, NULL);
DWORD ID = GetProcessId("notepad.exe");
if (!CreateRemoteThreadInject(ID, dll)) cout<<"failure";
else cout << "success";
return 0;
}
Thanks.
Be carefull on x64 x86 binaries
On windows 7 / 8 / 10 notepad.exe is a 64 bits process, so you need to compile your DLL & injector in x64
I have found a code that promises to intercept and detour calls to the TerminateProcess function and thus prevent my software from being killed directly from other program.
But this code is not working and I am still able to kill my process via other program.
Here is the last my attempt with a code I have found in this YouTube video:
PS: victim.exe is the killer program.
DLL
// DllRedirectAPI.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <Windows.h>
BYTE MOV[10] = { 0x48, 0xB8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
BYTE JMP_RAX[2] = { 0xFF, 0xE0 };
#define BuffSizeX64 (sizeof(MOV) + sizeof(JMP_RAX))
BOOL Hook_Det_x64(char LibName[], char API_Name[], LPVOID NewFun) {
DWORD OldProtect;
DWORD64 OrgAddress = (DWORD64)GetProcAddress(LoadLibraryA(LibName), API_Name);
if (OrgAddress == NULL) return 0;
memcpy(&MOV[2], &NewFun, 8);
VirtualProtect((LPVOID)OrgAddress, BuffSizeX64, PAGE_EXECUTE_READWRITE, &OldProtect);
memcpy((LPVOID)OrgAddress, MOV, sizeof(MOV));
memcpy((LPVOID)(OrgAddress + sizeof(MOV)), JMP_RAX, sizeof(JMP_RAX));
VirtualProtect((LPVOID)OrgAddress, BuffSizeX64, OldProtect, &OldProtect);
return 1;
}
int WINAPI MessageBoxAX(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType) {
MessageBoxExA(0, "Hooked ...", "Mahmoud", 0, 0);
return 999;
}
BOOL WINAPI DllMain(HMODULE hModule, DWORD Call_Reason, LPVOID lpReserved) {
switch (Call_Reason) {
case DLL_PROCESS_ATTACH:
Hook_Det_x64("Kernel32.dll", "TerminateProcess", MessageBoxAX);
}
return 1;
}
INJECTOR
// Injector.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <conio.h>
#include <stdio.h>
#include <comdef.h>
#define WIN32_LEAN_AND_MEAN
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
BOOL Inject(DWORD pID, const char * DLL_NAME);
DWORD GetTargetThreadIDFromProcName(const char * ProcName);
int main(int argc, char * argv[])
{
//############### CHANGE HERE ONLY ###################
char *Target_Process = "victim.exe"; //###
//#######################################################
char *buf;
DWORD pID = GetTargetThreadIDFromProcName(Target_Process);
buf = "DllRedirectAPI.dll";
if (!Inject(pID, buf))
{
printf("DLL Not Loaded!");
}
else{
printf("DLL is Injected in torget Process");
}
_getch();
return 0;
}
BOOL Inject(DWORD pID, const char * DLL_NAME)
{
HANDLE Proc;
char buf[50] = { 0 };
LPVOID RemoteString, LoadLibAddy;
if (!pID)
return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (!Proc)
{
sprintf_s(buf, "OpenProcess() failed: %d", GetLastError());
printf(buf);
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
}
DWORD GetTargetThreadIDFromProcName(const char * ProcName)
{
PROCESSENTRY32 pe;
HANDLE thSnapShot;
BOOL retval, ProcFound = false;
thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (thSnapShot == INVALID_HANDLE_VALUE)
{
printf("Error: Unable create toolhelp snapshot!");
return false;
}
pe.dwSize = sizeof(PROCESSENTRY32);
retval = Process32First(thSnapShot, &pe);
while (retval)
{
if (_bstr_t(pe.szExeFile) == _bstr_t(ProcName))
{
return pe.th32ProcessID;
}
retval = Process32Next(thSnapShot, &pe);
}
return 0;
}
Can someone help me, telling me where I'm making a mistake?
My system is Windows 7 Ultimate 64 Bits.
Thanks in advance.
(Wanted to write a comment, but it got quite long...)
As #AndrewMedico says in the comment: You need to hook the TerminateProcess of the Task Manager process to prevent the Task Manager from terminating anything.
I suggest you the following approach:
Try a simple DLL injection
a/ Make a DLL which prints some text in its DllMain, e.g. printf("I am here\n"); fflush(stdout);
b/ Try to inject it into some other command line process using the process hacker's Miscellaneous>Inject DLL...
c/ Verify your DLL was executed inside the target process by checking it's standard output
Try a simple API hook:
a/ Make a command line application which waits for a key and then terminates itself using some variant of TerminateProcess(GetCurrentProcess(), 1);. Add code to print some text after the TerminateProcess call.
b/ Run this application to verify the text after calling the TerminateProcess is not printed.
c/ Hook the TerminateProcess before waiting for the key using, e.g. mhook. Print some text in the replacement function and then return. Do not call the original TerminateProcess here.
d/ Run this application to verify the text inside the hook is printed and the text after the TerminateProcess call is printed as well (i.e. verify the process termination was suppressed).
Combine the results of previous steps to reach your goal:
a/ Put the hooking code from from step 2 into the DLL from step 1
b/ Inject it into the application from step 2b (i.e. the one without the hook) while it is waiting for the key and verify the text after TerminateProcess is printed.
c/ Enjoy (or debug/blame me)
Good luck!
EDIT>
OK, here is my view of what we have here:
Code in the question:
(Is an application very similar to what I suggest in "2b")
Hooks the TerminateProcess and shows a message box instead.
Should display a message box when executed
(Looks like it is a 32-bit only version)
YouTube video
Shows an application "Terminate process.exe" which terminates process given by name
After the "Injector.exe" is executed the application ceases to terminate the process and displays a message box instead (IMHO the "Injector.exe" injects a "DllFile.dll" into the running "Terminate process.exe")
Source code for the injector in the YouTube comments
This code injects DLL "C:\DllRedirectAPI.dll" into the first process with name "victim.exe" it finds
(It does not inject into "Terminate process.exe", it does not use "DllFile.dll")
Source code for the DLL in the YouTube comments
This code hooks function MessageBoxA that it shows a different message box instead. It is worth noting that the hook code itself calls the original MessageBoxA and takes the approach that it reverts the modification it did during the hooking, calls the original function and then re-applies the hook.
(It does not hook 'TerminateProcess' at all)
(Looks like it is a 32-bit only version)
64-bit version excerpts
Destructive hook of MessageBoxA (i.e. does not backup the original code)
The hook uses MessageBoxExA (which is intact) to display a different message box instead (i.e. it does not use the overwritten MessageBoxA)
(It does not hook 'TerminateProcess' at all)
(It is a 64-bit version)
Disclaimer: I am not that proficient with the topic to be 100% sure, feel free to correct/clarify me.
For the actual hooking I personally recommend to use the mhook library, which worked for me. It's documentation is worth reading as well.
See e.g. this for some alternatives (I have not tried any of them)...
EDIT>
This one works for me on Win XP inside VirtualBox:
#include <windows.h>
#include <stdio.h>
#include <mhook.h>
static BOOL WINAPI
(*_TerminateProcess)(
_In_ HANDLE hProcess,
_In_ UINT uExitCode
) = NULL;
BOOL WINAPI
TerminateProcessImpl(
_In_ HANDLE hProcess,
_In_ UINT uExitCode) {
printf("\nBlocked\n"); fflush(stdout);
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) {
if(Reason==DLL_PROCESS_ATTACH) {
printf("\nDLL attached!\n"); fflush(stdout);
HMODULE h = LoadLibrary("Kernel32");
if(h!=NULL) {
printf("\nGot Kernel32!\n"); fflush(stdout);
_TerminateProcess=(void*)GetProcAddress(h,"TerminateProcess");
if(_TerminateProcess!=NULL) {
printf("\nAbout to hook...\n"); fflush(stdout);
if(Mhook_SetHook((void*)&_TerminateProcess, &TerminateProcessImpl)) {
printf("\nHooked OK!\n"); fflush(stdout);
} else {
printf("\nHook failed!\n"); fflush(stdout);
}
}
}
}
return TRUE;
}
I posted a recent question on SO about code injection, this one is similar but not the same. I am injecting dll into Firefox, it injects successfully but the code in the DLL doesn't run. If i inject the same code into a custom application, it works. Why might that be. This is the code that I'm using.
Injector.exe // the file that's injecting the code
#include <stdio.h>
#include <windows.h>
#define procId 2844
#define dllname "dllinject.dll" // located in same directory
int main()
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, procId);
LPVOID allocated = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(dllname), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, (LPVOID)allocated, dllname, strlen(dllname), NULL);
LPVOID libaddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)libaddr, NULL, NULL);
CloseHandle(hProc);
return 0;
}
Simpleinjected.exe // the file being injected
#include <stdio.h>
int main()
{
printf("Hello");
return 0;
}
dllinject.dll
#include <windows.h>
int message(const char *msg)
{
MessageBox(NULL, msg, "Message from Dll", MB_OK);
return 0;
}
BOOL WINAPI DLLMain(HINSTANCE hInstDll, DWORD ulReason, LPVOID lpReserved)
{
switch(ulReason)
{
case DLL_PROCESS_ATTACH:
message("process attach");
break;
case DLL_THREAD_ATTACH:
message("thread attach");
break;
case DLL_PROCESS_DETACH:
message("process detach");
break;
case DLL_THREAD_DETACH:
message("thread detach");
break;
}
return true;
}
It works when injected into simpleinjected.exe but when injected in Firefox, nothing happens even though the dll is injected successfully.
I cannot reproduce your observations. I was able to inject dllinject.dll into other processes (also firefox) but I've never seen a message box.
After a bit of digging I found that your DLLMain is spelled wrong. Change it into DllMain and you'll see message boxes in Firefox.
By the way: You propably want to change MessageBox into MessageBeep since FireFox creates/destroys a lot of threads... (this is annoying even for a quick test!)
Im trying to get a basic hook going using microsoft detours. My program is able to successfully run CreateProcessWithDllEx and inject a dll. However, I cannot seem to resume the actual hooked program. I am using notepad for testing and I can see notepad.exe running in my process list, but the notepad window never actually comes up.
my dll is as follows:
#undef UNICODE
#include <cstdio>
#include <windows.h>
#include <detours.h>
#pragma comment(lib, "detours.lib")
typedef void (WINAPI *pFunc)(void);
DWORD WINAPI MyFunc(void);
pFunc FuncToDetour = (pFunc)DetourFindFunction("Winmm.dll", "timeGetTime"); //Set it at address to detour in
//the process
extern "C" __declspec( dllexport )VOID NullExport( VOID )
{
}
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hDLL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//DetourAttach(&(PVOID&)FuncToDetour, MyFunc);
//DetourTransactionCommit();
}
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)FuncToDetour, MyFunc);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
DWORD WINAPI MyFunc()
{
return 0;
}
And my injector is as follows:
#undef _UNICODE
#include "stdafx.h"
#include <cstdio>
#include <windows.h>
#include <detours.h>
int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
WCHAR DirPath[MAX_PATH+1];
wcscpy_s(DirPath, MAX_PATH, L"C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2010\\Projects\\hbotinjector\\Release");
char DLLPath[MAX_PATH+1] = "C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2010\\Projects\\hbotinjector\\Release\\hbotdll.dll";
WCHAR EXE[MAX_PATH+1]={0};
wcscpy_s( EXE, MAX_PATH, L"C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2010\\Projects\\hbotinjector\\Release\\notepad.exe" );
STARTUPINFO _StartupInfo;
PROCESS_INFORMATION _Information;
ZeroMemory( &_Information, sizeof( PROCESS_INFORMATION ) );
if(DetourCreateProcessWithDllEx( EXE, NULL, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED, NULL, DirPath, &_StartupInfo, &_Information,
DLLPath, NULL ))
{
MessageBoxA(NULL,"INJECTED", NULL, NULL);
ResumeThread(_Information.hThread);
WaitForSingleObject(_Information.hProcess, INFINITE);
}
else
{
char error[100];
sprintf(error, "%d", GetLastError());
MessageBoxA(NULL, error, NULL, NULL);
}
return 0;
}
And I build my dll with a .def file, insuring that there is the required function at ordinal 1 for detours to work properly:
LIBRARY HBOTDLL
EXPORTS
NullExport #1
Does anyone know what is causing the process from not running? As a side note, I've tried it with a blank dll as well where it just contains the required function at ordinal 1 and nothing else and it seems to have identical results.
Also, my injector runs forever as long as the notepad.exe process is showing in the process list. This is in response to WaitForSingleObject, which seems to indicate the process has been spawned correctly.
On the comment of Hans Passant, I went back and realized that I had declared pi and si as well as _Information and _StartupInfo. I wasn't zeroing out the second group I had created, and that was the group I was using. So I changed the call to CreateProcessWithDllEx to use &pi and &si. Everything works fine now.