GetFullPathNameA的Dll注入不起作用

Dll injection with GetFullPathNameA not working?

本文关键字:不起作用 注入 Dll GetFullPathNameA      更新时间:2023-10-16

如果我显式写入地址,dll注入工作

char s[1000]="E:\worldisnotenough.dll"; //Works

如果我使用GetFullPathNameA DLL注入不起作用,并且它们不会产生任何运行时或编译时错误。我检查了这个:

char s[1000];
int ax =GetFullPathNameA("worldisnotenough.dll",
                  1000,
                  s, //Output to save the full DLL path
                  NULL);
  std::cout<<s;  //prints the correct path. Working.

cout << s打印正确的路径,但DLL注入不会发生。没有出现错误。我检查了VirtualAllocEx、WriteProcessMemory和CreateRemoteThread,它们都正常工作。

编辑:完成代码

#include <QCoreApplication>
#include<windows.h>
#include<tchar.h>
#include<iostream>
#include "E:/Users/Gen/qt project freiza/FreizaLibrary/freizalibrary.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
//    FreizaLibrary lib;
//    QTextStream s(stdin);
//    QString value = s.readLine();
//    lib.injection(value.toInt());
int procID = 13044;
  HANDLE  hHandle = OpenProcess( PROCESS_CREATE_THREAD |
                           PROCESS_QUERY_INFORMATION |
                           PROCESS_VM_OPERATION |
                           PROCESS_VM_WRITE |
                           PROCESS_VM_READ,
                           FALSE,
                           procID );
  QString dllName = "worldisnotenough.dll";
  QFile myDllFile(dllName);
  QFileInfo dllInfo(dllName);
  QString str =dllInfo.absoluteFilePath();
  char s[]="E:\Users\Gen\qt project freiza\build-libtester-FreizaKit-Release\release\worldisnotenough.dll";
std::cout<<strlen(s)<<"n";
  int ax =GetFullPathNameA("worldisnotenough.dll",
                  86,   //I set it to 1000 before posting this question.
                  s, //Output to save the full DLL path
                  NULL);
//qDebug()<< QString::fromUtf8(s) <<" "<< ax;
  std::cout<<s<<"size "<<ax;
  LPVOID dllPathAddr = VirtualAllocEx(hHandle,
                               0,
                               strlen(s),
                               MEM_RESERVE|MEM_COMMIT,
                               PAGE_EXECUTE_READWRITE);
std::cout<<" test n";
std::cout<<(int*)dllPathAddr<<endl;
if(dllPathAddr==NULL)
{
    qDebug()<<"virtual failed";
}
size_t x;
 int n= WriteProcessMemory(hHandle,
                     dllPathAddr,
                     s,
                     strlen(s),
                     &x);
  if(n==0)
  {
      qDebug()<<"write failed";
  }
  std::cout<<endl<<n<<"t"<<x;
  LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
  if(addr==NULL)
  {
      qDebug()<<"get proc failed";
  }
  HANDLE rThread = CreateRemoteThread(hHandle, NULL, 0, (LPTHREAD_START_ROUTINE)addr,dllPathAddr, 0, NULL);
  if(rThread==NULL)
  {
      qDebug()<<"create remote failed";
  }
  WaitForSingleObject(rThread, INFINITE);
  VirtualFreeEx(hHandle, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hHandle);
  qDebug()<< "done";
    return a.exec();
}

为什么投反对票?当我发布完整代码时。人们说只发布不起作用的代码段。我充分地解释了情况。由于这些反对票,我现在将无法就斯塔克夫弗洛提出问题。非常感谢。

您的问题是试图使用静态定义的字符数组作为GetFullPathNameA的缓冲区!

请参阅此处:

    char s[]="E:\Users\Gen\qt project freiza\build-libtester-FreizaKit-Release\release\worldisnotenough.dll";
std::cout<<strlen(s)<<"n";
  int ax =GetFullPathNameA("worldisnotenough.dll",
                  86,   //1000 is no good, MAX_PATH is 260
                  s, //Using 's' as a buffer? Don't do that please!
                  NULL);

此外,当使用由"A"表示的ANSI版本时,最大路径长度为260个字符。最大路径==260

"在该函数的ANSI版本中,名称限制为MAX_PATH字符。若要将此限制扩展到32767个宽字符,请调用该函数的Unicode版本并在前面加上"\\"

修复代码:(然而,我不使用QT,所以这里缺少了QT,这应该无关紧要,因为它没有用于注入工作所需的任何东西)

#include <windows.h>
#include <iostream>
#include <tlhelp32.h>
HANDLE GetProcessHandle(wchar_t *ProcessName,ULONG *ReturnedProcessId);
int main(int argc, char *argv[])
{
    ULONG procID;
    HANDLE hHandle=GetProcessHandle(L"ExeToInjectInto.exe",&procID);
    /*HANDLE hHandle=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|
                               PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,procID);*/
    std::cout<<"handle: "<<hHandle<<" process ID: "<<procID<<"n";
    char s[]="C:\Users\DBVM_OS\CodeBlocksProjects\HelpFreizaProject\bin\Debug\mytestdll.dll";
    std::cout<<s<<"n"<<strlen(s)<<"n";
    //First Problem:
    /*In the ANSI version of this function, the name is limited to MAX_PATH characters.
     To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\?"
    */
    //Second Problem:
    /* Don't use a defined static char[] as a buffer! allocate some memory or use the stack */
    //char s2[MAX_PATH];
    //int ax=GetFullPathNameA("mytestdll.dll",MAX_PATH,s2,0);
    char *s2=new char[MAX_PATH];
    if(s2==0) return 0;
    int ax=GetFullPathNameA("mytestdll.dll",MAX_PATH,s2,0);
    std::cout<<s2<<"nsize returned: "<<ax<<" strlen: "<<strlen(s2)<<"n";
    LPVOID dllPathAddr=VirtualAllocEx(hHandle,0,(strlen(s2)+1),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    std::cout<<"Remotely Allocated String Address: n";
    std::cout<<(int*)dllPathAddr<<"n";
    if(dllPathAddr==0)
    {
        OutputDebugStringA("VirtualAllocEx failed...");
        return 0;
    }
    SIZE_T x;
    BOOL n=WriteProcessMemory(hHandle,dllPathAddr,s2,(strlen(s2)+1),&x);
    if(n==FALSE)
    {
        OutputDebugStringA("write failed");
        VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
        CloseHandle(hHandle);
        return 0;
    }
    std::cout<<"WriteProcessMemory Success: "<<n<<", Bytes Written: "<<x<<"n";
    LPVOID addr=(LPVOID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryA");
    if(addr==0)
    {
        OutputDebugStringA("get proc failed");
        VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
        CloseHandle(hHandle);
        return 0;
    }
    std::cout<<"LoadLibraryA: "<<addr<<"n";
    HANDLE rThread=CreateRemoteThread(hHandle,0,0,(LPTHREAD_START_ROUTINE)addr,dllPathAddr,0,0);
    if(rThread==0)
    {
        OutputDebugStringA("create remote failed");
        VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
        CloseHandle(hHandle);
        return 0;
    }

    WaitForSingleObject(rThread,INFINITE);
    std::cout<<"DLL Should have been injected successfully at this point...nFreeing remote string";
    BOOL freed=VirtualFreeEx(hHandle,dllPathAddr,0,MEM_RELEASE);
    if(freed==0) OutputDebugStringA("Freeing Remote String Failed...");
    delete[] s2; //if you dynamically allocated s2 like I've done...
    CloseHandle(hHandle);
    return 0;
}
HANDLE GetProcessHandle(wchar_t *ProcessName,ULONG *ReturnedProcessId)
{
    PROCESSENTRY32W pe;
    HANDLE Snap;
    ZeroMemory(&pe, sizeof(PROCESSENTRY32W));
    pe.dwSize=sizeof(PROCESSENTRY32W);
    Snap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(Snap==INVALID_HANDLE_VALUE) return 0;
    BOOL bProcess=Process32FirstW(Snap,&pe);
    while(bProcess)
    {
        if(_wcsicmp(pe.szExeFile,ProcessName)==0)
        {
            HANDLE ProcessHandle=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|
                               PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,pe.th32ProcessID);
            if(ReturnedProcessId!=0)
                *ReturnedProcessId=pe.th32ProcessID;
            CloseHandle(Snap);
            return ProcessHandle;
        }
        bProcess=Process32NextW(Snap, &pe);
    }
    if(ReturnedProcessId!=0) *ReturnedProcessId=0;
    CloseHandle(Snap);
    return 0;
}

您需要使用

 strlen(s)+1 

因为它返回字符串的长度,而不包括终止的null字符本身!因此,VirtualAllocEx和WriteProcessMemory不会写入"\0"字符,文件名将终止于内存中的"随机"位置。

还有

 char s[]="E:\Users\Gen\qt project freiza\build-libtester-FreizaKit-Release\release\worldisnotenough.dll"; //- Length: 93+1
 int ax =GetFullPathNameA("worldisnotenough.dll",
              sizeof(s), //<-- old: 86 but s[] is 93 + 1 if this has to hold the total path may it was to small?
              s, //Output to save the full DLL path
              NULL);

看起来王?!