I'm dealing with 2 new things: writing a DLL and injecting it in another process. I think I inject it successfully because if I try to delete it I get a message that tells me it is used by another program.
I followed this steps in Visual Studio 2008 http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.80%29.aspx but I wrote it in C, not C++.
And this is the code
DWORD
APIENTRY
DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
printf("Hello World\n");
Sleep(5000); // added this to make sure I see it when it happens
return TRUE;
}
I created an application that references the DLL just like in the MSDN documentation said and it works (it prints Hello World).
At each step in my DLL injection program I check for errors and print them. So I know that no function fails.
I check the exit code and it is 1927086080 which I don't know what means.
I don't know if it's needed, but here is the C source for my program.
#include <stdio.h>
#include <windows.h>
#include <string.h>
int main(int argc, TCHAR* argv[])
{
DWORD procId = 0;
DWORD pathLen = 0;
DWORD writeProcMemory = 0;
DWORD exitCode = 0;
HANDLE hProc = NULL;
HANDLE hDll = NULL;
HANDLE hThread = NULL;
LPVOID baseAdr = NULL;
LPVOID fAdr = NULL;
procId = atoi((char*)argv[1]);
pathLen = strlen((LPCSTR)argv[2]);
if(0 == pathLen)
{
printf("Check DLL path\n");
return 0;
}
// Open process
hProc = OpenProcess(PROCESS_ALL_ACCESS,
0,
procId);
if(NULL == hProc)
{
printf("OpenProcess failed\nGetLastError() = %d\n",
GetLastError());
return 0;
}
// Allocate memory
baseAdr = VirtualAllocEx(hProc,
0,
pathLen + 1,
MEM_COMMIT,
PAGE_READWRITE);
if(NULL == baseAdr)
{
printf("VirtualAllocEx failed\nGetLastError() = %d\n",
GetLastError());
CloseHandle(hProc);
return 0;
}
// write my dll path in the memory I just allocated
if(!WriteProcessMemory(hProc,
baseAdr,
argv[2],
pathLen + 1,
0))
{
printf("WriteProcessMemory failed\nGetLastError() = %d\n",
GetLastError());
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
// get kernel32.dll
hDll = LoadLibrary(TEXT("kernel32.dll"));
if(NULL == hDll)
{
printf("LoadLibrary failed\nGetLastError() = %d\n",
GetLastError());
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
// get LoadLibraryA entry point
fAdr = GetProcAddress(hDll,
"LoadLibraryA");
if(NULL == fAdr)
{
printf("GetProcAddress failed\nGetLastError() = %d\n",
GetLastError());
FreeLibrary(hDll);
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
// create remote thread
hThread = CreateRemoteThread(hProc,
0,
0,
fAdr,
baseAdr,
0,
0);
if(NULL == hThread)
{
printf("CreateRemoteThread failed\nGetLastError() = %d\n",
GetLastError());
FreeLibrary(hDll);
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
WaitForSingleObject(hThread,
INFINITE);
if(GetExitCodeThread(hThread,
&exitCode))
{
printf("exit code = %d\n",
exitCode);
}
else
{
printf("GetExitCode failed\nGetLastError() = %d\n",
GetLastError());
}
CloseHandle(hThread);
FreeLibrary(hDll);
VirtualFreeEx(hProc,
baseAdr,
0,
MEM_RELEASE);
CloseHandle(hProc);
return 0;
}
Now, when I inject a shellcode (with a slightly different program than the one above) into a process, I can see in process explorer how my shell code starts running and that the victim process is his parent. Here, I see nothing, but again, it's the first time I'm working with DLLs.
But it still gets loaded because I can't delete the dll file until I kill the victim process.
Also, when I run my injection program, I can see it doing nothing for 5 seconds so it's like the printf is skipped.
Doing this on Windows 7 x64. I know that there are cases in which CreateRemoteThread isn't working on Windows 7, but I use it in my shell code injection and it works and I use the same targets here.
UPDATE: changing my DLL to call ExitProcess(0); kills the victim process, so it all comes down to me not knowing how to print something.
How can I get it to print something?
You want to get messages from your DLL but you use printf. How can you see DLL's printf output? You better write your information to a file.
#define LOG_FILE L"C:\\MyLogFile.txt"
void WriteLog(char* text)
{
HANDLE hfile = CreateFileW(LOG_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD written;
WriteFile(hfile, text, strlen(text), &written, NULL);
WriteFile(hfile, "\r\n", 2, &written, NULL);
CloseHandle(hfile);
}
void WriteLog(wchar_t* text)
{
HANDLE hfile = CreateFileW(LOG_FILE, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD written;
WriteFile(hfile, text, wcslen(text) * 2, &written, NULL);
WriteFile(hfile, L"\r\n", 4, &written, NULL);
CloseHandle(hfile);
}
Replace all your printf calls with my function and see what happens actually. By the way, if you have thread in your DLL you can write log every second that will ensure you your code works. You can add time into log file too.
I think if you have enough privilege to inject a DLL into a process, nothing will stop you. Change your code and tell me what happens in log file.
Good luck
Related
I use this function as usual, but the debug traces (OutputDebugString) don't work from injecting dlls. And in the target application no thread is created (I look through the process hacker)
GetlastError says 0
CreateRemoteThread says tid
but WaitForSingleObject exits immediately (why if all ok!?)
... I'm confused %
OS windows 10 x64
app and dll - x86
code dll is:
#include <stdio.h>
#include <windows.h>
WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID res)
{
CHAR pszMessage[1024] = { 0 };
sprintf(pszMessage, ("L2Proj: GetCurrentProcessId() %d, hModule 0x%p, nReason %d\r\n"), GetCurrentProcessId(), h, reason);
OutputDebugString(pszMessage);
switch(reason) {
case DLL_PROCESS_ATTACH:
//MessageBoxA(NULL, "inject success", "done", MB_OK);
TerminateProcess(GetCurrentProcess(), -1);
break;
}
return TRUE;
}
PS TerminateProcess in dll doesn't work either
PPS GetExitCodeThread() after WaitForSingleObject ends is 0
What it the problem with?
ADDED
APP code is:
NOTE: This is just test code (no control over return values / wrong label name codestyle etc.), pls do not tell me about it.
I wrote step by step in the comments which functions return which values
// process of course has access
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
// handle is valid
if(!hProcess) {
return GetLastError();
}
DWORD id;
char str[] = "G:\\workspace\\proj\\test.dll";
void *l = (void*)GetProcAddress(
GetModuleHandle("kernel32.dll"), "LoadLibraryA");
// addr is valid
if(!l) {
return 35;
}
DWORD str_size = strlen(str) + 1;
// memory addr is valid
LPVOID lp = VirtualAllocEx(hProcess, NULL, str_size, MEM_COMMIT |
MEM_RESERVE, PAGE_READWRITE);
BOOL res = WriteProcessMemory(hProcess, lp, str, str_size, NULL);
// res is true
HANDLE h = CreateRemoteThread(hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)l,
lp,
0,
&id);
// handle is valid
// id is valid (tid remote thread)
if(!h) {
return GetLastError();
}
DWORD err = GetLastError();
CHAR pszMessage[1024] = { 0 };
sprintf(pszMessage, ("L2Proj: GetProcessId() %d\r\n"), id);
OutputDebugString(pszMessage);
// ends immediately (no waiting)
WaitForSingleObject(h, INFINITE);
GetExitCodeThread(h, &id);
//id is 0 (exit code)
sprintf(pszMessage, ("L2Proj: GetExitCodeThread() %d (GetLastError=%d)\r\n"), id, err);
OutputDebugString(pszMessage);
// the only error after this function (VirtualFreeEx)
// GetLastError gives 87 (0x57) - ERROR_INVALID_PARAMETER
VirtualFreeEx(hProcess, lp, 0, MEM_RELEASE);
CloseHandle(h);
CloseHandle(hProcess);
I forgot, i use g++ (GCC) 9.3.0 - maybe the problem is because of this?
I solved the problem, just change the compiler.
Yes, the problem was with the compiler, everything works fine on the Microsoft compiler.
Thanks for answers.
problem in you not use debugger – RbMm yesterday
and yes, I always use the debugger, thanks a lot ...
I am trying to write a DLL injector to perform a DLL injector on a calculator process.
I wrote the DLL injector program in C and the DLL but the injector dosent inject the DLL or any other DLL (I tried to take some random windows DLL that the calculator doesn't use).
#include <stdio.h>
#include <Windows.h>
int main() {
LPCSTR dllpath = "C:\\Users\\......\\Dll1.dll";
printf("#### Starting ####\n");
printf("step 1: attaching the target process memory\n");
HANDLE hProcess = OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
6456 // target process id
);
if (hProcess != NULL) {
printf("step 2: allocate the target memory process\n");
LPVOID dllPathMemoryAddr = VirtualAllocEx(
hProcess,
NULL,
strlen(dllpath),
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE
);
if (dllPathMemoryAddr != NULL) {
printf("step 3: write to the process memory\n");
BOOL succeededWriting = WriteProcessMemory(
hProcess,
dllPathMemoryAddr,
dllpath,
strlen(dllpath),
NULL
);
if (succeededWriting) {
printf("step 4: execute.\n");
FARPROC loadLibAddr = GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"LoadLibraryA"
);
HANDLE rThread = CreateRemoteThread(
hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)loadLibAddr,
dllPathMemoryAddr,
0,
NULL
);
}
}
CloseHandle(hProcess);
}
return TRUE;
}
after running the injector I get this output:
#### Starting ####
step 1: attaching the target process memory
step 2: allocate the target memory process
step 3: write to the process memory
step 4: execute.
after that, I am still unable to see in process explorer the new DLL.
You are calling GetProcAddress() to get the address of LoadLibraryA(), this is returning the address of LoadLibraryA in your local process not the injected one. This is not guaranteed to be correct in the external process. You do not need to get the address manually, CreateRemoteThread will resolve the address for you.
Here is a very simple injector example that will explain how to do it
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
DWORD GetPid(char * targetProcess)
{
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap && snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!_stricmp(pe.szExeFile, targetProcess))
{
CloseHandle(snap);
return pe.th32ProcessID;
}
} while (Process32Next(snap, &pe));
}
}
return 0;
}
int main()
{
char * dllpath = "C:\\Users\\me\\Desktop\\dll.dll";
char * processToInject = "csgo.exe";
long pid = 0;
while (!pid)
{
pid = GetPid(processToInject);
Sleep(10);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void * loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllpath, strlen(dllpath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);
CloseHandle(hThread);
}
CloseHandle(hProc);
return 0;
}
I found the problem. I compiled the DLL as 64 but accidentally compiled the DLL injector has complied as 32 bit.
My OS is Windows 8.1 64 bit . My program is to inject a DLL file to a target process,and when this DLL file attached to a process , it will create a .txt file on D: and write some words into it and save .It is just a test.But when I compile my program as a 32 bit program and my DLL code is compiled as 32 bit , it succeed , it can create the file and save the content . But when I compile my code of DLL and my program as 64 bit , it hasnot throw any exception , all seems that it succeed . But you cannot find the .txt file it create . So , it fails , not excuting the things you want to do .
The follow is my code of my DLL
#include "stdafx.h"
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
BOOL create();
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
create();
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOL create()
{
wchar_t FileName[] = L"D:\\x64injecttest.txt";
HANDLE hFile = ::CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("createfile fails,the error code is:%u\n", GetLastError());
system("PAUSE");
return 0;
}
char str[] = "if you see this file,then you have success\n";
WriteFile(hFile, str, strlen(str) + 1, NULL, NULL);
CloseHandle(hFile);
return TRUE;
}
The follow is the code of my program
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<TlHelp32.h>
LPTHREAD_START_ROUTINE lpThreadProc; //pointes to the address of LoadLibraryW API
typedef DWORD(WINAPI *pFunction)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, BOOL CreateSuspended, DWORD dwStackSize, DWORD dw1, DWORD dw2, LPVOID pUnknown); //I inject DLL to other process with the NtCreateThreadEx API , and this function pointer would point to the address of this API
DWORD SearchForTarget(wchar_t target[])
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
printf("fails when createtoolhelp32snapshot,the error code is:%u\n", GetLastError());
system("PAUSE");
exit(-1);
}
BOOL b = ::Process32First(hSnap, &pe32);
while (b)
{
printf("the process name is:%ws\n", pe32.szExeFile);
printf("the process id is:%u\n", pe32.th32ProcessID);
if (wcscmp(pe32.szExeFile, target) == 0)
return pe32.th32ProcessID;
b = Process32Next(hSnap, &pe32);
}
return -1;
}
BOOL InjectDLL(DWORD pid)
{
wchar_t DLLPath[] = L"C:\\Users\\Dell-pc\\Desktop\\x64InjectTest\\Debug\\DLL.dll";
DWORD length = wcslen(DLLPath);
DWORD trueLength = length * 2 + 2;
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("openprocess fails,the error code is:%u\n", GetLastError());
system("PAUSE");
exit(-1);
}
LPVOID pBaseAddress = ::VirtualAllocEx(hProcess, NULL, trueLength, MEM_COMMIT, PAGE_READWRITE);
if (pBaseAddress == NULL)
{
printf("virtualallocex fails,the error code is:%u\n", GetLastError());
system("PAUSE");
exit(-1);
}
BOOL b = WriteProcessMemory(hProcess, pBaseAddress, DLLPath, trueLength, NULL);
if (b == 0)
{
printf("writeprocessmemory fail,the error code is:%u\n", GetLastError());
system("PAUSE");
exit(-1);
}
HMODULE hModule = ::LoadLibrary(L"kernel32.dll");
lpThreadProc = (LPTHREAD_START_ROUTINE)::GetProcAddress(hModule, "LoadLibraryW");
HMODULE hNtdll = ::LoadLibrary(L"ntdll.dll");
pFunction pFunc = (pFunction)GetProcAddress(hNtdll, "NtCreateThreadEx");
printf("it is ready to create thread\n");
HANDLE hRemoteThread;
pFunc(&hRemoteThread, 0x1FFFFF, NULL, hProcess, lpThreadProc, pBaseAddress, FALSE, NULL, NULL, NULL, NULL);
if (hRemoteThread == NULL)
{
printf("nrcreateprocessex fails,the error code is:%u\n", GetLastError());
system("PAUSE");
exit(-1);
}
WaitForSingleObject(hRemoteThread, INFINITE);
return TRUE;
}
int main()
{
wchar_t target[] = L"notepad.exe"; //inject my DLL to notepad.exe
DWORD pid = SearchForTarget(target);
if (pid == -1)
{
printf("not find the target \n");
system("PAUSE");
return -1;
}
InjectDLL(pid);
system("PAUSE");
return 0;
}
I compile my code (both my program and my DLL ) as 32 bit , and run it on my Windows 8.1 64 bit OS , it succeed . But when I compile it (both my program and my DLL) as 64 bit , it hasnot throw any exception , and it seems it succeed , only except it has not create the file and write some words into it (and this is what should do when the DLL attached to the process ) . So , anyone know where the problem is ? One more thing , I use Visual Studio 2013 .
I'd guess that the line causing you the 32/64-bit problem in your example is the following.
lpThreadProc = (LPTHREAD_START_ROUTINE)::GetProcAddress(hModule,
"LoadLibraryW");
This gives you the address of LoadLibraryW in your current process, not that target process. Given the target process is 64-bit, the address is 99.99999% going to be different.
Even within 32-bit processes you shouldn't generally assume that DLLs will always load into the same address footprint.
To get around your issue you will probably have to enumerate modules within the target process and find your entry point from there. There are API's to help with this. A google for GetRemoteProcAddress will also point you in the right direction.
That aside, there are many other issues with your loader. Personally I'd advise you to use one that someone else has already written. There used to be plenty of good loaders around that cover many of the caveats and have multiple injection mechanisms too.
Thanks everyone , I have solved the problem . About the function NtCreateThreadEx , the type of the 8th , 9th and 10 th paramter (the stacksize parameter, the dw1 parameter , the dw2 parameter) should be SIZE_T , not DWORD . If it is DWORD , the it has no problem when you compile the code as 32 bit , but it would not work if you compile it as 64 bit .
So , this line of code should be written as below
typedef NTSTATUS (WINAPI *pFunction)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, BOOL CreateSuspended, SIZE_T dwStackSize, SIZE_T dw1, DWORD SIZE_T, LPVOID pUnknown);
Can someone provide me with a sample C code that list´s all device Names that i can open with Createfile()? i always get error code 3 : path does not exist
sample code that doesnt works:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <regstr.h>
#include <devioctl.h>
#include <usb.h>
#include <usbiodef.h>
#include <usbioctl.h>
#include <usbprint.h>
#include <setupapi.h>
#include <devguid.h>
#include <wdmguid.h>
#pragma comment(lib, "Setupapi.lib")
int main(void){
HDEVINFO deviceInfoList;
deviceInfoList = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (deviceInfoList != INVALID_HANDLE_VALUE)
{
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoList, i, &deviceInfoData); i++)
{
LPTSTR buffer = NULL;
DWORD buffersize = 0;
while (!SetupDiGetDeviceInstanceIdA(deviceInfoList, &deviceInfoData, buffer, buffersize, &buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer) delete buffer;
buffer = new TCHAR[buffersize];
}
else
{
printf("%ls\n", "error");
break;
}
}
HANDLE hFile = CreateFileA(buffer,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("InvalidHandle, error code: %d\n", GetLastError());
}
CloseHandle(hFile);
printf("%s\n", buffer);
if (buffer) { delete buffer; buffer = NULL; }
}
}
getchar();
}
my Goal is to print all valid device Names and try to get a valid handle on it that i can later user for sending ioctl`s
thx
EDIT:
ok abhineet so thats what i got now :
DWORD EnumerateDevices(){
DWORD dwResult = 0;
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);// DIGCF_ALLCLASSES
/*HDEVINFO hdev =SetupDiGetClassDevs(NULL,
0, // Enumerator
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES); */
if (INVALID_HANDLE_VALUE != hdev) {
for (int idev = 0; idev < 100; idev++)
{
SP_DEVICE_INTERFACE_DATA did = { 0 };
did.cbSize = sizeof(did);
if (SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did))
{
DWORD cbRequired = 0;
SetupDiGetDeviceInterfaceDetail(hdev,
&did,
NULL,
0,
&cbRequired,
0);
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, cbRequired);
if (pdidd) {
pdidd->cbSize = sizeof(*pdidd);
if (SetupDiGetDeviceInterfaceDetail(hdev, &did, pdidd, cbRequired, &cbRequired, 0)) {
wprintf(L"%s\n", pdidd->DevicePath);
HANDLE hBattery = CreateFile(pdidd->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != hBattery)
{
printf("Successfully opened Handle\n");
CloseHandle(hBattery);
}
else{
wprintf(L"CreateFile(%s) failed %d\n", pdidd->DevicePath, GetLastError());
}
}
else{
printf("SetupDiGetDeviceInterfaceDetail() failed %d\n", GetLastError());
}
LocalFree(pdidd);
}
}
else{
printf("SetupDiGetDeviceInterfaceDetail() failed %d\n", GetLastError());
}
}
else if (ERROR_NO_MORE_ITEMS == GetLastError())
{
printf("-NoMoreItems-");
break; // Enumeration failed - perhaps we're out of items
}
}
SetupDiDestroyDeviceInfoList(hdev);
}
else{
printf("SetupDiGetClassDevs() failed %d\n", GetLastError());
}
return dwResult;
}
i ripped the most from here : https://msdn.microsoft.com/en-us/library/windows/desktop/bb204769(v=vs.85).aspx
and my Output is :
\\?\acpi#pnp0c0a#1#{72631e54-78a4-11d0-bcf7-00aa00b7b32a}
Successfully opened Handle
-NoMoreItems-
at least i got a valid handle!
so i wanna do this an all devices avaible on the System , how to do that?
IMHO, I don't think, you can do a CreateFile on InstanceID. To do a CreateFile, you need the symbolic name of the device. You can use the following SetupAPIs,
SetupDiEnumDeviceInterfaces
SetupDiGetDeviceInterfaceDetail
The Remark section of both APIs state that,
SetupDiEnumDeviceInterfaces:: DeviceInterfaceData points to a structure that identifies a requested
device interface. To get detailed information about an interface, call
SetupDiGetDeviceInterfaceDetail. The detailed information includes the
name of the device interface that can be passed to a Win32 function
such as CreateFile (described in Microsoft Windows SDK documentation)
to get a handle to the interface.
SetupDiGetDeviceInterfaceDetail:: The interface detail returned by this function consists of a device path that can be passed to Win32
functions such as CreateFile. Do not attempt to parse the device path
symbolic name. The device path can be reused across system starts.
This might be of your use, how to get DevicePath from DeviceID
I'm still working on my same project (in case you wondering why I ask so many questions.)
Anyway I switched from compiler, from mingw32 (mingw.org) to MinGW-w64 (mingw-w64.sourceforge.net/)
While the project compiles fine without any error, the injector doesn't work, without giving any errors or something. Here is the source:
int Inject(DWORD pID)
{
HANDLE hProcess;
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID)))
return 0;
char* szDllName = "subclass64.dll";
LPVOID LoadLibraryAddress;
if ((LoadLibraryAddress = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA")) == NULL)
{
char buf[32];
sprintf(buf, "%d", GetLastError());
MessageBox(0, buf, "", 0);
CloseHandle(hProcess);
return 0;
}
LPVOID lpStringAddress;
if ((lpStringAddress = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(szDllName), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL)
{
char buf[32];
sprintf(buf, "%d", GetLastError());
MessageBox(0, buf, "", 0);
CloseHandle(hProcess);
return 0;
}
if (WriteProcessMemory(hProcess, lpStringAddress, szDllName, strlen(szDllName), NULL) == 0)
{
char buf[32];
sprintf(buf, "%d", GetLastError());
MessageBox(0, buf, "", 0);
CloseHandle(hProcess);
return 0;
}
HANDLE hThread;
if ((hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpStringAddress, 0, NULL)) == NULL)
{
char buf[32];
sprintf(buf, "%d", GetLastError());
MessageBox(0, buf, "", 0);
CloseHandle(hProcess);
return 0;
}
CloseHandle(hProcess);
return 1;
}
I debugged as well, but I didn't get any weird values:
(gdb) p hProcess
$1 = (HANDLE) 0xec
(gdb) p LoadLibraryAddress
$2 = (LPVOID) 0x7f9de0528ac <LoadLibraryA>
(gdb) p lpStringAddress
$3 = (LPVOID) 0x8a4d10000
(gdb) p hThread
$4 = (HANDLE) 0xf0
(gdb) p GetLastError()
$5 = 0
Nothing is wrong with the DLL because it works fine with another DLL Injector (from the internet)
Edit: It works fine with a dummy/test application, but it doesn't with notepad for example (which works with using an third party injector.)
Hopefully someone could help me, regards
One problem is that the name of the DLL in the target process is not null terminated, as only strlen(szDllName) bytes are being allocated and written. Change the the string handling logic to allocate and write strlen(szDllName) + 1 to ensure the string is null terminated.
Note that the DLL to be injected, subclass64.dll, must be in the same directory as the target process or its PATH environment variable must include the directory were the DLL resides.
I switched from compiler to Visual Studio, in there it didn't worked at first but then it did. The answer for this is not to debug. So you navigate to the path of the application and then start the program manually.