Before my dll file gets injected to a process, I want to check if it actually is the process I want it to inject. Is there a way to achieve this, so I could abort the injection process if its the wrong process?
Thank you in advance for any help!
int APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
if (reason == DLL_PROCESS_ATTACH)
{
if (process == theprocessiwant)
{
//call my stuff....
}
}
return true;
}
GetModuleFileNameA will give you the complete path of the executable of whose process you have injected into. Compare this path against your predefined executable path.
Okay thank you for your suggestions, I found a working way!
DWORD targetProcessId;
int APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (_stricmp(entry.szExeFile, "target.exe") == 0)
{
targetProcessId = entry.th32ProcessID;
}
}
}
CloseHandle(snapshot);
if (reason == DLL_PROCESS_ATTACH)
{
if (GetCurrentProcessId() == targetProcessId)
{
//MY Code
}
}
return true;
}
Related
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?
I'm trying to inject a dll into a process. The dll does nothing except return TRUE.
I attached a debugger to the process that I want to inject into and confirmed that LoadLibraryA is called correctly but returns NULL.
Now I think that this might have something to do with my dll's dependencies. So I checked them and found out that it requires vcruntime140.dll.
The process that I want to inject my dll into does not load that dll.
#include "pch.h"
extern "C" int __stdcall APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#include "Source.h"
const char* DllName = "InjectMe.dll";
int main()
{
DWORD processID = 0;
printf("Process ID: ");
scanf_s("%i", &processID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if (handle == nullptr) {
printf("Process could not be opened.");
return -1;
}
LPVOID memDllName = VirtualAllocEx(handle, nullptr, strlen(DllName) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
assert(memDllName != nullptr);
assert(WriteProcessMemory(handle, memDllName, DllName, strlen(DllName) + 1, nullptr));
LPVOID loadLibraryAddr = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
assert(loadLibraryAddr != nullptr);
HANDLE thread = CreateRemoteThreadEx(handle, nullptr, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddr, memDllName, CREATE_SUSPENDED, nullptr, nullptr);
assert(thread != nullptr);
ResumeThread(thread);
DWORD returnCode = WaitForSingleObject(thread, 5000);
CloseHandle(thread);
if (returnCode == WAIT_TIMEOUT) {
printf("DLL was not loaded. Thread timed out.");
return -1;
}
else if (returnCode == WAIT_OBJECT_0) {
printf("DLL was successfully injected into the process.");
}
CloseHandle(handle);
std::cin.get();
return 0;
}
You must use a full file path not a relative file path when calling LoadLibrary()
const char* DllName = "InjectMe.dll";
needs to be changed to something like this
const char* DllName = "c:\\Users\User\\Desktop\\InjectMe.dll";
Also make sure you run as administrator if OpenProcess fails or sometimes you also need to use SeDebugPrivelage
In order to test if it is a pathing issue, try the following. Keep the
const char* DllName = "InjectMe.dll";
Then put the InjectMe.dll and your .exe in the same directory and try to run your exe. If the dll is loaded successfully, then it is a pathing issue.
To work around that, you can either specify the full path like GuidedHacking said, OR you can put your InjectMe.dll in the same directory as the .vcxproj and .cpp files (not where the .sln file is)
I'm trying make a hook in MessageBoxA api in a remote process made by me using IAT hook tecnique. I'm using Process Hacker software for inject my dll file into my process and until here works fine.
My unique trouble is that MessageBoxA never is intercepted when i will call this api from my application.
I have discovered that this api don't can be found in table of import of my process.
So, i want know any suggestion about how i can find this api on table.
Here is code that i use:
#include <windows.h>
#include <string.h>
#include <stdio.h>
void HookFunction(char* funcName, LPDWORD function);
LPDWORD FoundIAT(char* funcName);
int WINAPI HookMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if(dwReason == DLL_PROCESS_ATTACH)
{
MessageBox(NULL, "Injeted with success!", "Hello", NULL);
HookFunction("MessageBoxA", (LPDWORD)&HookMessageBoxA);
}
return TRUE;
}
void HookFunction(char* funcName, LPDWORD function)
{
LPDWORD pOldFunction = FoundIAT(funcName);
DWORD accessProtectionValue , accessProtec;
int vProtect = VirtualProtect(pOldFunction, sizeof(LPDWORD), PAGE_EXECUTE_READWRITE, &accessProtectionValue);
*pOldFunction = (DWORD)function;
vProtect = VirtualProtect(pOldFunction, sizeof(LPDWORD), accessProtectionValue, &accessProtec);
}
int WINAPI HookMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
return MessageBoxA(hWnd, "Hello", "DLL answering here!", uType);
}
LPDWORD FoundIAT(char* funcName)
{
DWORD test = 0;
LPVOID pMapping = GetModuleHandle(NULL);
if (pMapping == NULL)
exit(-1);
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER) pMapping;
if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
exit(-1);
PIMAGE_NT_HEADERS NtHeaders = (PIMAGE_NT_HEADERS) ((char*) DosHeader + DosHeader->e_lfanew);
if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
exit(-1);
PIMAGE_DATA_DIRECTORY DataDirectory = &NtHeaders->OptionalHeader.DataDirectory[1];
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR) ((char*) DosHeader + DataDirectory->VirtualAddress);
PIMAGE_THUNK_DATA32 OriginalFirstThunk = (PIMAGE_THUNK_DATA32)((char*) DosHeader + ImportDescriptor->OriginalFirstThunk);
while(OriginalFirstThunk != 0)
{
DWORD name = (DWORD)((char*) pMapping + ImportDescriptor->Name);
OriginalFirstThunk = (PIMAGE_THUNK_DATA32)((char*) DosHeader + ImportDescriptor->OriginalFirstThunk);
PIMAGE_THUNK_DATA32 FirstThunk = (PIMAGE_THUNK_DATA32)((char*) DosHeader + ImportDescriptor->FirstThunk);
while(OriginalFirstThunk->u1.AddressOfData != 0)
{
PIMAGE_IMPORT_BY_NAME NameImg = (PIMAGE_IMPORT_BY_NAME)((char*) DosHeader + (DWORD)OriginalFirstThunk->u1.AddressOfData);
test = (DWORD)OriginalFirstThunk->u1.Function & (DWORD)IMAGE_ORDINAL_FLAG32;
if (test == 0)
{
if(strcmp(funcName, (const char*)NameImg->Name) == 0)
{
MessageBox(NULL, NameImg->Name, "", NULL);
return (LPDWORD)&(FirstThunk->u1.Function);
}
}
OriginalFirstThunk++;
FirstThunk++;
}
ImportDescriptor++;
}
return 0;
}
Source
EDIT 1:
I have seen with more datails, that now this code is able to find MessageBoxA api :D, but still when i'll call this api from my application (made in Delphi), the hook don't work.
:-(
My Delphi code here:
procedure TForm1.btn1Click(Sender: TObject);
begin
MessageBoxA(Application.Handle, 'Delphi application here!', 'Hello',0);
end;
EDIT 2:
This can be a definitive solution, but link is offline. Someone can help me about how it can be adapted to my code above please?
When error occurs in the program, on the screen we can see something like this:
Is there anyway to determine this situation using c++ winapi? I have aldready tried to use this code to find out if the main thread of the procces is suspend. But it doesn't.
I also tried to send timeot messages(code below) but result is always true, even if error window have appeared.
typedef struct tagENUMINFO
{
// In Parameters
DWORD PId;
// Out Parameters
HWND hWnd;
HWND hEmptyWnd;
HWND hInvisibleWnd;
HWND hEmptyInvisibleWnd;
} ENUMINFO, *PENUMINFO;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
DWORD pid = 0;
PENUMINFO pInfo = (PENUMINFO)lParam;
TCHAR szTitle[_MAX_PATH+1];
// sanity checks
if (pInfo == NULL)
// stop the enumeration if invalid parameter is given
return(FALSE);
// get the processid for this window
if (!::GetWindowThreadProcessId(hWnd, &pid))
// this should never occur :-)
return(TRUE);
// compare the process ID with the one given as search parameter
if (pInfo->PId == pid)
{
// look for the visibility first
if (::IsWindowVisible(hWnd))
{
// look for the title next
if (::GetWindowText(hWnd, szTitle, _MAX_PATH) != 0)
{
pInfo->hWnd = hWnd;
// we have found the right window
return(FALSE);
}
else
pInfo->hEmptyWnd = hWnd;
}
else
{
// look for the title next
if (::GetWindowText(hWnd, szTitle, _MAX_PATH) != 0)
{
pInfo->hInvisibleWnd = hWnd;
}
else
pInfo->hEmptyInvisibleWnd = hWnd;
}
}
// continue the enumeration
return(TRUE);
}
HWND GetMainWindow(DWORD PId)
{
ENUMINFO EnumInfo;
// set the search parameters
EnumInfo.PId = PId;
// set the return parameters to default values
EnumInfo.hWnd = NULL;
EnumInfo.hEmptyWnd = NULL;
EnumInfo.hInvisibleWnd = NULL;
EnumInfo.hEmptyInvisibleWnd = NULL;
// do the search among the top level windows
::EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)&EnumInfo);
// return the one found if any
if (EnumInfo.hWnd != NULL)
return(EnumInfo.hWnd);
else if (EnumInfo.hEmptyWnd != NULL)
return(EnumInfo.hEmptyWnd);
else if (EnumInfo.hInvisibleWnd != NULL)
return(EnumInfo.hInvisibleWnd);
else
return(EnumInfo.hEmptyInvisibleWnd);
}
DWORD GetProcessByExeName(char *ExeName)
{
DWORD Pid;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return false;
}
if (Process32First(hProcessSnap, &pe32))
{
do
{
if (strcmpi(pe32.szExeFile, ExeName) == 0)
{
CloseHandle(hProcessSnap);
return pe32.th32ProcessID;
}
} while (Process32Next(hProcessSnap, &pe32));
}
CloseHandle(hProcessSnap);
return 0;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR cmdline, int show)
{
HWND Hwnd;
LRESULT res;
DWORD PID;
PID=GetProcessByExeName("procces.exe");
Hwnd=GetMainWindow(PID);
res = SendMessageTimeout(Hwnd, WM_NULL, NULL, NULL, SMTO_ABORTIFHUNG, 3000,NULL);
//res == 1 always
}
Yes there is a way, all crash interceptors work this way, like the firefox crash reporter.
On windows you can use structured exception handling:
reference:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680657(v=vs.85).aspx
and howto:
http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus
extract:
LONG WINAPI MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionPtrs)
{
// Do something, for example generate error report
//..
// Execute default exception handler next
return EXCEPTION_EXECUTE_HANDLER;
}
void main()
{
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
// .. some unsafe code here
}
I found another solution. This error message has it's own procces WerFault.exe, we can simply destroy it with TerminateProcess() and the hang procces will be destroyed too. And then it is quite simple to notice that the required process does not exist.
I have a function with blow detail.
typedef part
typedef DWORD (WINAPI *GETMODULEFILENAMEEX)(HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName,DWORD nSize);
typedef BOOL (WINAPI *PFNTERMINATEPROCESS)(HANDLE hProcess,UINT uExitCode);
/// GetProcessName function
void GetProcessName(DWORD PID, PTSTR szProcessName, size_t cchSize)
{
HMODULE lib=LoadLibrary(TEXT("Psapi.dll"));
GetModuleFileNameEx=(GETMODULEFILENAMEEX)GetProcAddress
(lib,"GetModuleFileNameExW");
_tcscpy_s(szProcessName, cchSize, TEXT("---"));
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,PID);
if (hProcess == NULL) {
_tcscpy_s(szProcessName, cchSize, TEXT("???"));
return;
}
if (GetModuleFileNameEx(hProcess,(HMODULE)0, szProcessName, cchSize)
== 0) {
if (!GetProcessImageFileName(hProcess, szProcessName, cchSize)) {
_tcscpy_s(szProcessName, cchSize, TEXT("???"));
}
}
CloseHandle(hProcess);
}
I want use this function in below function
BOOL WINAPI Hook_TerminateProcess(HANDLE hProcess,UINT uExitCode) {
BOOL nResult=false;
TCHAR szProcessName[MAX_PATH];
nResult = ((PFNTERMINATEPROCESS)(PROC) g_TerminateProcess)(hProcess,uExitCode);
GetProcessName(HandleToULong(hProcess),szProcessName,MAX_PATH); //my question here
MessageBox(0, szProcessName ,TEXT("My MessageBox Info"),MB_OK | MB_ICONERROR);
return(nResult);
}
When I call function GetProcessName, this must return process name but it ??? str always.
I call this function directly by PID, for example GetProcessName(2018,szProcessName,MAX_PATH);.
2018 for example is a pid and it work.
I don't know why HandleToULong(hProcess) doesn't work. My hProcess must be a handle
type certainly now how I fix this problem?
char name[MAX_PATH * 2 ] = "\0", *p;
GetModuleFileName(GetModuleHandle(NULL),name,MAX_PATH);
p = name + strlen(name) - 1;
while (isalnum(*p) || ('.' == *p) || ('_' == *p))
p--;
p++;
std::cout << p << std::endl;
You must call GetProcessId rather than HandleToULong. You need a process ID, not a handle-converted-to-an-unsigned-long
How can you terminate the process then expect the handle to still be valid? cause if any clean up is performed, all data is lost(you don't explicitly copy the handle, so this can happen)
your error seems to stem from where your retrieving hProcess, in which case you should check GetLastError to see why its failing
In Windows, a process ID is different from a process handle. You are taking the process handle in Hook_TerminateProcess and passing it into GetProcessName as a process ID. This will never work.
You should refactor GetProcessName to take a handle and then have an overload that takes a process ID. The process ID overload does the OpenProcess work to convert it into a handle and the CloseHandle work to clean it up.
After the refactoring, you'll have two methods:
void GetProcessName(HANDLE hProcess, PTSTR szProcessName, size_t cchSize);
void GetProcessName(DWORD PID, PTSTR szProcessName, size_t cchSize);