DLL Injection into notepad - c++

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

Related

I want to hook win32API CreateFileW by detours and print callstack information captured by CaptureStackBackTrace

I use detours to hook win32 api CreateFile and use CaptureStackBackTrace to get callstack information. and then resolve symbol by SymFromAddr api. but the result shown in terminal is only error 126 and error 184. And I only invoke ShowTraceStack function one time while trace information is more than one. I do not know what happened, can someone help me?
#include <windows.h>
#include <stdio.h>
#include "detours.h"
#include <fstream>
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib") //Windows API PathFileExists
#include <io.h>
#pragma comment(lib, "detours.lib")
#include <DbgHelp.h> //SymInitialize
#pragma comment(lib,"dbghelp.lib")
#define STACK_INFO_LEN 20000
struct stackInfo {
PDWORD hashValue; // hash value to identify same stack
char* szBriefInfo; // callstack info
};
stackInfo ShowTraceStack(char* szBriefInfo)
{
static const int MAX_STACK_FRAMES = 200;
void* pStack[MAX_STACK_FRAMES];
static char szStackInfo[STACK_INFO_LEN * MAX_STACK_FRAMES];
static char szFrameInfo[STACK_INFO_LEN];
HANDLE process = GetCurrentProcess(); // The handle used must be unique to avoid sharing a session with another component,
SymInitialize(process, NULL, TRUE);
PDWORD hashValue = (PDWORD)malloc(sizeof(DWORD)); // allow memory for hashVavlue, it will be rewrited in function CaptureStackBackTrace
WORD frames = CaptureStackBackTrace(0, MAX_STACK_FRAMES, pStack, hashValue);
//printf("hash value is: %ud \n", &hashValue);
if (szBriefInfo == NULL) {
strcpy_s(szStackInfo, "stack traceback:\n");
}
else {
strcpy_s(szStackInfo, szBriefInfo);
}
for (WORD i = 0; i < frames; ++i) {
DWORD64 address = (DWORD64)(pStack[i]);
DWORD64 displacementSym = 0;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
DWORD displacementLine = 0;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
if (SymFromAddr(process, address, &displacementSym, pSymbol) &&
SymGetLineFromAddr64(process, address, &displacementLine, &line))
{
_snprintf_s(szFrameInfo, sizeof(szFrameInfo), "\t%s() at %s:%d(0x%x)\n",
pSymbol->Name, line.FileName, line.LineNumber, pSymbol->Address);
}
else
{
_snprintf_s(szFrameInfo, sizeof(szFrameInfo), "\terror: %d\n", GetLastError());
}
strcat_s(szStackInfo, szFrameInfo);
}
stackInfo traceStackInfo;
traceStackInfo.hashValue = hashValue;
traceStackInfo.szBriefInfo = szStackInfo;
printf("%s", szStackInfo);
return traceStackInfo;
}
HANDLE(*oldCreateFile)(LPCWSTR,
DWORD,
DWORD,
LPSECURITY_ATTRIBUTES,
DWORD,
DWORD,
HANDLE) = CreateFileW;
HANDLE WINAPI newCreateFile(
_In_ LPCWSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
) {
ShowTraceStack((char*)"trace information.");
return oldCreateFile(
L".\\newFiles.txt", // L".\\NewFile.txt", // Filename
//lpFileName,
dwDesiredAccess, // Desired access
dwShareMode, // Share mode
lpSecurityAttributes, // Security attributes
dwCreationDisposition, // Creates a new file, only if it doesn't already exist
dwFlagsAndAttributes, // Flags and attributes
NULL);
}
void hook() {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)oldCreateFile, newCreateFile);
DetourTransactionCommit();
}
void unhook()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)oldCreateFile, newCreateFile);
DetourTransactionCommit();
}
void myProcess() {
HANDLE hFile = CreateFile(TEXT(".\\CreateFileDemo.txt"),
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
OutputDebugString(TEXT("CreateFile fail!\r\n"));
}
// write to file
const int BUFSIZE = 4096;
char chBuffer[BUFSIZE];
memcpy(chBuffer, "Test", 4);
DWORD dwWritenSize = 0;
BOOL bRet = WriteFile(hFile, chBuffer, 4, &dwWritenSize, NULL);
ShowTraceStack((char*)"trace information.");
if (bRet)
{
OutputDebugString(TEXT("WriteFile success!\r\n"));
}
}
int main(){
hook();
myProcess();
unhook();
}

Download a file when a DLL injected to my process

I am trying to use DLL to download an update for exe file.
#include "pch.h"
#include<tchar.h>
#include<urlmon.h>
#pragma comment (lib,"urlmon.lib")
int main()
{
TCHAR path[MAX_PATH];
GetCurrentDirectory(MAX_PATH, path);
wsprintf(path, TEXT("%s\\update.exe"), path);
//printf("Path: %S\n", path);
HRESULT res = URLDownloadToFile(NULL, _T("getupdate"), path, 0, NULL);
if (res == s_OK )
{
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD reason,
LPVOID lpReserved
)
{
if (reason == DLL_PROCESS_ATTACH)
{
// MessageBoxA(NULL, "hello world", "wlekfjkej", MB_OK);
main();
/* const auto thread = CreateThread(nullptr,
0, reinterpret_cast<LPTHREAD_START_ROUTINE>(main),
hModule,
0, nullptr);
*/
}
}
So the problem is - HRESULT returning s_OK response which stands for - everything is ok and file downloaded. But it doesnt...
How can i get this method to work ? maybe some alternatives to urldownload func to use here?

C and C++ library error [duplicate]

This question already has an answer here:
"undefined reference to" errors when linking static C library with C++ code
(1 answer)
Closed 6 years ago.
I got 3 files (selfdelxp.c, selfdelxp.h and main.cpp)
selfdelxp.c was copied from http://blogorama.nerdworks.in/selfdeletingexecutables/ and I removed the main function as I try to use the SelfDelete() function in main.cpp
The problem comes when I try to compile it throwing the error undefined reference to 'SelfDelete()'
How can I make it work? What am I doing wrong? What I'm trying to do is to be able to use that function (SelfDelete()) in a program written in main.cpp
selfdelxp.c
//
// Self-deleting exe under Windows XP
//
#include <windows.h>
#include <tchar.h>
// get this right!
#define EXPLORER_PID 1444
typedef UINT (WINAPI * WAIT_PROC)(HANDLE, DWORD); // WaitForSingleObject
typedef BOOL (WINAPI * CLOSE_PROC)(HANDLE); // CloseHandle
typedef BOOL (WINAPI * DELETE_PROC)(LPCTSTR); // DeleteFile
typedef VOID (WINAPI * EXIT_PROC)(DWORD); // ExitProcess
typedef struct
{
WAIT_PROC fnWaitForSingleObject;
CLOSE_PROC fnCloseHandle;
DELETE_PROC fnDeleteFile;
EXIT_PROC fnExitProcess;
HANDLE hProcess;
TCHAR szFileName[MAX_PATH];
} INJECT;
#pragma optimize("gsy", off)
#pragma check_stack(off) // doesn't work :-(
DWORD WINAPI RemoteThread(INJECT *remote)
{
remote->fnWaitForSingleObject(remote->hProcess, INFINITE);
remote->fnCloseHandle(remote->hProcess);
remote->fnDeleteFile(remote->szFileName);
remote->fnExitProcess(0);
return 0;
}
#pragma check_stack
HANDLE GetRemoteProcess()
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
//return OpenProcess(PROCESS_ALL_ACCESS, FALSE, EXPLORER_PID);
if(CreateProcess(0, "explorer.exe", 0, 0, FALSE, CREATE_SUSPENDED|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi))
{
CloseHandle(pi.hThread);
return pi.hProcess;
}
else
{
return 0;
}
}
PVOID GetFunctionAddr(PVOID func)
{
#ifdef _DEBUG
// get address of function from the JMP <relative> instruction
DWORD *offset = (BYTE *)func + 1;
return (PVOID)(*offset + (BYTE *)func + 5);
#else
return func;
#endif
}
BOOL SelfDelete()
{
INJECT local, *remote;
BYTE *code;
HMODULE hKernel32;
HANDLE hRemoteProcess;
HANDLE hCurProc;
DWORD dwThreadId;
HANDLE hThread = 0;
char ach[80];
hRemoteProcess = GetRemoteProcess();
if(hRemoteProcess == 0)
return FALSE;
// Allocate memory in remote process
code = VirtualAllocEx(hRemoteProcess, 0, sizeof(INJECT) + 128, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(code == 0)
{
CloseHandle(hRemoteProcess);
return FALSE;
}
hKernel32 = GetModuleHandle(_T("kernel32.dll"));
// setup remote structure
remote = (INJECT *)(code + 128);
local.fnWaitForSingleObject = (WAIT_PROC)GetProcAddress(hKernel32, "WaitForSingleObject");
local.fnCloseHandle = (CLOSE_PROC)GetProcAddress(hKernel32, "CloseHandle");
local.fnExitProcess = (EXIT_PROC)GetProcAddress(hKernel32, "ExitProcess");
#ifdef UNICODE
local.fnDeleteFile = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileW");
#else
local.fnDeleteFile = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileA");
#endif
// duplicate our own process handle for remote process to wait on
hCurProc = GetCurrentProcess();
DuplicateHandle(hCurProc, hCurProc, hRemoteProcess, &local.hProcess, 0, FALSE, DUPLICATE_SAME_ACCESS);
// find name of current executable
GetModuleFileName(NULL, local.szFileName, MAX_PATH);
// write in code to execute, and the remote structure
WriteProcessMemory(hRemoteProcess, code, GetFunctionAddr(RemoteThread), 128, 0);
WriteProcessMemory(hRemoteProcess, remote, &local, sizeof(local), 0);
wsprintf(ach, "%x %x\n", code, remote);
OutputDebugString(ach);
// execute the code in remote process
hThread = CreateRemoteThread(hRemoteProcess, 0, 0, code, remote, 0, &dwThreadId);
if(hThread != 0)
{
CloseHandle(hThread);
}
return TRUE;
}
/*int main(void)
{
SelfDelete();
return 0;
}*/
selfdelxp.h
#ifndef SELFDELETE_H_
#define SELFDELETE_H_
#include <stdbool.h>
bool SelfDelete(void);
#endif // SELFDELETE_H_
main.cpp
#include <iostream>
#include "selfdelxp.h"
using namespace std;
int main()
{
SelfDelete();
return 0;
}
You're getting caught out by C++ name mangling. Note selfdelxp.c is presumably compiled as C code. You need to add extern "C" { ... } around the SelfDelete() deceleration or try compiled selfdelxp.c as cpp (e.g. rename it).
Here is how you would do it with the first approach.
#include <windows.h>
extern "C" {
BOOL SelfDelete();
}
(You could also declare that using C++ bool and probably be okay but afik it is better to include windows.h and use the same type)

C++ Code Injection crashes injected application

I'm trying to inject a simple executable into another executable that I made, unfortunately, whenever I inject the code into the executable, it says 'simpleinjected.exe has stopped working' then it closes. I'm using CreateRemoteThread to inject the code. This is what I have done so far.
Injector.exe // the file that's injecting the code
#include <stdio.h>
#include <windows.h>
#define procId 2844
#define executable "executable.exe" // located in same directory
int main()
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, procId);
LPVOID allocated = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(executable), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, (LPVOID)allocated, executable, strlen(executable), 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;
}
executable.exe // the executable being injected into simpleinjected
#include <windows.h>
int main()
{
MessageBox(NULL, "Injected successfully", "Code Injection", MB_OK);
return 0;
}
The message is not displaying and simpleinjected.exe crashes. The crash shows that the code was inserted but I don't understand why it's crashing.
When using DLL and the same technique above, the dll executes in the 'simpleinjected.exe' but doesn't work when injected into Firefox. The dll code is below. It executes in the custom application but not Firefox even though it's injected successfully.
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;
}
modified code of Simpleinjected.exe as these below. and then try inject dllinject.dll to Simpleinjected.exe again.
#include <stdio.h>
int main()
{
while(true)
{
printf("Hello");
}
return 0;
}
you should modify the defines below as same as Simpleinjected.exe.
#define procId 2844 //process id of Simpleinjected.exe
#define executable "dllinject.dll" // located in same directory

CreateProcessWithDLLEx-Hooked process starts but can't resume

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.