Search code examples
cwindowswinapidlldll-injection

my dll injection . succeed when compiled as 32 bit , but failed when compiled as 64 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 .


Solution

  • 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);