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;
}
Related
Firstly, I want to hook CreateFile() and rewrite it. Then I want to recode the callstack of my new CreateFile() function. But when I use SymInitialize() to Initialize a handle, it falls into an endless loop. Through my debug, the reason is SymInitialize() invokes CreateFile(). So why does SymInitialize() involve CreateFile()? How to avoid this loop? Is there any alternative method to record callstack information to avoid this loop?
#include <windows.h>
#include <stdio.h>
#include "detours.h"
#include <fstream>
#include <io.h>
#pragma comment(lib, "detours.lib")
#include <DbgHelp.h> //SymInitialize
#pragma comment(lib,"dbghelp.lib")
#define STACK_INFO_LEN 200
struct stackInfo {
PDWORD hashValue; // hash value to identify same stack
char* szBriefInfo; // callstack info
};
stackInfo ShowTraceStack(char* szBriefInfo)
{
static const int MAX_STACK_FRAMES = 12;
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;
return traceStackInfo;
//printf("%s", szStackInfo);
}
HANDLE (*__stdcall 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.\n");
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);
if (bRet) {
OutputDebugString(TEXT("WriteFile success!\r\n"));
}
}
int main(){
hook();
myProcess();
unhook();
}
The main problem is the call to SymInitialize where you pass through "TRUE" for fInvadeProcess parameter. This is causing it to SymLoadModuleEx to be called for each loaded module. This will cause a lot of file access to download / create / open PDB files for each loaded module. This is the reason for your infinite loop.
The "quick" fix for this sample is to move the call to SymInitialize into your main before the hook call as it only needs to be called once. This means all the PDB modules are loaded before the hooking / call to ShowTraceStack.
The other problems are:
dbghelp API is NOT thread safe - so this example will not work in a multi-threaded application
SymFromAddr may call CreateFile as well for the same reason to load a newly loaded module PDB information - so your hook not passing through the filename will cause PDB information to not work
If you are trying to make someone more useful I would:
Move SymInitialize to main before the hooking (called only once)
Only call CaptureStackBackTrace in the hook and queue the thread stack information to be processed at a later time
Create a separate thread the takes the CaptureStackBackTrace stack information output and convert it to a stack trace - this would is the only thread calling the dbghlp API making calls to dbghlp API thread safe
In your hook detect when being called from the dbghlp API usage thread and don't do the stack trace and don't modify the CreateFile parameters so you don't get into a infinite loop
I want to get the process and thread handles about some games to inject dll, and I used OpenProcess() and OpenThread() to obtain these handles. But I found that I just get different handles each time I use these functions. And they are useless for me because they arent the true handles. Please tell me how I can get the true handles?
Thanks for your answers and comments! And I found that I did not describe my problem very well. Sorry.
Actually, if i used CreateProcess() funtion to launch a process and get handles from parameter lpProcessInformation pi. I could inject my dll into game through these handles named pi.hProcess and pi.hThread. And these handles seem like would not change during the program's runtime.
But if I got handles from OpenProcess() and OpenThread(), the process handle and thread handle were not same as the handle from CreateProcess() even though I got them in same run from a process.
So I thought that the handle from pi is the true handle, and the handle from OpenProcess() are fake. I dont know why they are different and why only handles from pi can work well.
Please tell me the difference about handles from OpenProcess() and
CreateProcess(). Or how I can get the handles same as CreateProcess() through PID.
This is the code how inject dll. And ony handles from pi.hProcess and pi.hThread can work.
void KInject::InjectDll(HANDLE hProcess, HANDLE hThread, ULONG_PTR param){
QueueUserAPC(
(PAPCFUNC)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"),
hThread,
(ULONG_PTR)param
);
}
void KInject::Inject2(HANDLE hProcess, HANDLE hThread, const char* szDLL ){
SIZE_T len = strlen(szDLL) + 1;
PVOID param = VirtualAllocEx(hProcess, NULL, len, MEM_COMMIT | MEM_TOP_DOWN /*MEM_RESERVE*/, PAGE_READWRITE);
if (param != NULL)
{
SIZE_T ret;
if (WriteProcessMemory(hProcess, param, szDLL, len, &ret)) {
InjectDll(hProcess, hThread, (ULONG_PTR)param );
}
}
}
This is the code how i get handles.
#include <Windows.h>
#include "tlhelp32.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
HWND hq = FindWindow(NULL, "Temp");
RECT rect;
DWORD dwThreadID;
DWORD dwProcessId;
GetWindowThreadProcessId(hq, &dwProcessId);
GetWindowRect(hq, &rect);
DWORD a = GetWindowThreadProcessId(hq, &dwProcessId);
THREADENTRY32 te32 = { sizeof(te32) };
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (Thread32First(hThreadSnap, &te32))
{
do {
if (dwProcessId == te32.th32OwnerProcessID)
{
dwThreadID = te32.th32ThreadID;
break;
}
} while (Thread32Next(hThreadSnap, &te32));
}
CloseHandle(hThreadSnap);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadID);
CloseHandle(hThread);
CloseHandle(hProcess);
return 0;
}
There is nothing wrong with the API in this regard. Their return values are just what they are supposed to be, i.e. "handles" to the actual processes and threads. Exactly the same way as when you open a file, you get a handle to it, and if you open the same file multiple times, you may get different handles.
Having said that, just in the same way that files do have a more permanent name—which is their paths—processes and threads also do have a more permanent name and its called their "ID".
You can use the Win32 functions GetProcessId(HANDLE handle) and GetThreadId(HANDLE handle) to get to these more permanent identifiers.
I found this code on the Internet but it says that is to be run on Windows XP.
I tried to run it on Windows 7 and it worked, but I wonder if it is safe, not just running this code, but also doing it on Windows 7.
//
// 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;
}
By the way, how could this be used as a library in C/C++?
My goal is to just use, for example,
#include "selfdel.h" so I can use just the function SelfDelete() in a C++ program.
You should realize what this code is. It's an injection of a code into another process which will be executed as that process and then the process will exit. It should just work (though look at the comments below). I think the author of this code snippet had written it before Win Vista was released, therefore the concern you have.
You can declare SelfDelete() in your "selfdel.h". Calling this function and exiting right away should do the trick.
The implementation doesn't require any input from user of the library since it gets everything it needs.
// duplicate our own process handle for remote process to wait on
hCurProc = GetCurrentProcess();
...
// find name of current executable
GetModuleFileName(NULL, local.szFileName, MAX_PATH);
Some comments:
Your process should have enough rights to create the other one
Such activity may be treated as suspicious by anti-virus software
Don't forget that "zombie" process will wait as long as your process lives after calling SelfDelete()
Consider other approaches: How can a program delete its own executable
I've been trying to figure out what's wrong for so long.
I've seen some people assign:
GetProcAddress(GetModuleHandle("KERNEL32.dll"), "LoadLibraryA")
And I wonder if that's what I have to do, but I just don't understand what that line of code does exactly. It has nothing to do with MY dll function, so why load it?
Main (console application A.K.A injector):
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>
char* dllPath = "C:\\Users\\Kalist\\Desktop\\Projects\\DLL\\bin\\Debug\\DLL.dll";
typedef DWORD (WINAPI *pThreadFunc)();
char* ProcToInject = "calc.exe";
int main(){
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
DWORD procID;
if(procSnap){
if(Process32First(procSnap, &pe32)){
do{
if(!strcmp(pe32.szExeFile, ProcToInject)){
procID = pe32.th32ProcessID;
break;
}
}while(Process32Next(procSnap, &pe32));
}
CloseHandle(procSnap);
}
HANDLE procAccess = OpenProcess(PROCESS_ALL_ACCESS, false, procID);
void* memSpace = VirtualAllocEx(procAccess, NULL, strlen(dllPath)+1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(procAccess, memSpace, dllPath, strlen(dllPath)+1, NULL);
HINSTANCE getLibadd = LoadLibrary(dllPath);
pThreadFunc pThreadFuncVar = (pThreadFunc)GetProcAddress(getLibadd, "threadFunc");
CreateRemoteThread(procAccess, NULL, 0, (LPTHREAD_START_ROUTINE)pThreadFuncVar, memSpace, 0, NULL);
CloseHandle(procAccess);
}
DLL remote process:
#include <iostream>
#include <windows.h>
extern "C" DWORD WINAPI threadFunc(){
MessageBox(0, "Injection worked!", "Injection message", MB_OK);
return 0;
}
The problem with your code is that pThreadFuncVar contains the address of threadFunc in your injector process. However, your Dll.dll is not even loaded in the target process. Even if your dll were loaded, it would likely not be loaded at the same address, so the pThreadFuncVar address would still be meaningless in the target process.
Only a few essentials modules, like KERNEL32, are loaded at the same address in every process. So, if you use the address of LoadLibraryA for CreateRemoteThread, it will load the dll from the path which you copied into the target process's memory. This will in turn call the dll attach procedure of your dll, which is where you want to put the MessageBox call.
Am working on a background appliation in vc++
How can i get the Process Name of the current Application for example "Iexplore" for Using Internet Explorer, "Skype" for window with tile "Skype - username", "Explorer" for using windows explorer ?
i referred this link but am getting Null error : http://www.codeproject.com/Articles/14843/Finding-module-name-from-the-window-handle
This can be done using the following code:
bool GetActiveProcessName(TCHAR *buffer, DWORD cchLen)
{
HWND fg = GetForegroundWindow();
if (fg)
{
DWORD pid;
GetWindowThreadProcessId(fg, &pid);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess)
{
BOOL ret = QueryFullProcessImageName(hProcess, 0, buffer, &cchLen);
//here you can trim process name if necessary
CloseHandle(hProcess);
return (ret != FALSE);
}
}
return false;
}
and then
TCHAR buffer[MAX_PATH];
if(GetActiveProcessName(buffer, MAX_PATH))
{
_tprintf(_T("Active process: %s\n"), buffer);
}
else
{
_tprintf(_T("Cannot obtain active process name.\n"));
}
Note though that QueryFullProcessImageName function is only available since Windows Vista, on earlier systems you could use GetProcessImageFileName (it is similar, but requires linkage with psapi.dll and returns device path instead of usual win32 path)
I used this code in my QT5/C++ project to get the currently active process name and window title successfully, based on some research (thanks #dsi). Just wanted to share the code so that someone else would benefit from it.
# Put this two declarations in the top of the CPP file
#include <windows.h>
#pragma comment(lib, "user32.lib")
And put the following into a method:
// get handle of currently active window
HWND hwnd = GetForegroundWindow();
if (hwnd) {
// Get active app name
DWORD maxPath = MAX_PATH;
wchar_t app_path[MAX_PATH];
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess) {
QueryFullProcessImageName(hProcess, 0, app_path, &maxPath);
// here you can trim process name if necessary
CloseHandle(hProcess);
QString appPath = QString::fromWCharArray(app_path).trimmed();
QFileInfo appFileInfo(appPath);
windowInfo.appName = appFileInfo.fileName();
}
// Get active window title
wchar_t wnd_title[256];
GetWindowText(hwnd, wnd_title, sizeof(wnd_title));
windowInfo.windowTitle = QString::fromWCharArray(wnd_title);
}
This code may not be compiled directly, because windowInfo is a parameter in my program. Please feel free to let me know in case you encountered any issues when trying this code.