【问题标题】:x64 in-memory executionx64 内存执行
【发布时间】:2018-02-16 10:22:15
【问题描述】:

我已将In-Memory Execution of an Executable 用作Release-x86,并将test_x86.exe 作为文件并正常工作:

/* In memory execution example */
/*
Author: Amit Malik
http://www.securityxploded.com
Compile in Dev C++
*/

#include 
#include 
#include 

#define DEREF_32( name )*(DWORD *)(name)

int main()
{
     char file[20];
     HANDLE handle;
     PVOID vpointer;
     HINSTANCE laddress;
     LPSTR libname;
     DWORD size;
     DWORD EntryAddr;
     int state;
     DWORD byteread;
     PIMAGE_NT_HEADERS nt;
     PIMAGE_SECTION_HEADER section;
     DWORD dwValueA;
     DWORD dwValueB;
     DWORD dwValueC;
     DWORD dwValueD; 

     printf("Enter file name: ");
     scanf("%s",&file);

     // read the file
     printf("Reading file..\n");
     handle = CreateFile(file,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

     // get the file size
     size = GetFileSize(handle,NULL);

     // Allocate the space 
     vpointer = VirtualAlloc(NULL,size,MEM_COMMIT,PAGE_READWRITE);

     // read file on the allocated space
     state = ReadFile(handle,vpointer,size,&byteread,NULL);
     CloseHandle(handle);
     printf("You can delete the file now!\n");
     system("pause");

     // read NT header of the file
     nt = PIMAGE_NT_HEADERS(PCHAR(vpointer) + PIMAGE_DOS_HEADER(vpointer)->e_lfanew);
     handle = GetCurrentProcess();

     // get VA of entry point
     EntryAddr = nt->OptionalHeader.ImageBase + nt->OptionalHeader.AddressOfEntryPoint;

     // Allocate the space with Imagebase as a desired address allocation request
     PVOID memalloc = VirtualAllocEx(
                                     handle, 
                                     PVOID(nt->OptionalHeader.ImageBase), 
                                     nt->OptionalHeader.SizeOfImage, 
                                     MEM_RESERVE | MEM_COMMIT, 
                                     PAGE_EXECUTE_READWRITE
                                     );

     // Write headers on the allocated space
     WriteProcessMemory(handle, 
     memalloc, 
     vpointer, 
     nt->OptionalHeader.SizeOfHeaders, 
     0
     );

     // write sections on the allocated space
     section = IMAGE_FIRST_SECTION(nt);
     for (ULONG i = 0; i < nt->FileHeader.NumberOfSections; i++) 
     {
         WriteProcessMemory(
                           handle, 
                           PCHAR(memalloc) + section[i].VirtualAddress, 
                           PCHAR(vpointer) + section[i].PointerToRawData, 
                           section[i].SizeOfRawData, 
                           0
                           );
     }

     // read import dirctory    
     dwValueB = (DWORD) &(nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);

     // get the VA 
     dwValueC = (DWORD)(nt->OptionalHeader.ImageBase) + 
                          ((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress;


     while(((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name)
     {
            // get DLL name
            libname = (LPSTR)(nt->OptionalHeader.ImageBase + 
                              ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name);

            // Load dll
            laddress = LoadLibrary(libname);

            // get first thunk, it will become our IAT
            dwValueA = nt->OptionalHeader.ImageBase + 
                                  ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->FirstThunk;

            // resolve function addresses
            while(DEREF_32(dwValueA))
            {
                dwValueD = nt->OptionalHeader.ImageBase + DEREF_32(dwValueA);
                // get function name 
                LPSTR Fname = (LPSTR)((PIMAGE_IMPORT_BY_NAME)dwValueD)->Name;
                // get function addresses
                DEREF_32(dwValueA) = (DWORD)GetProcAddress(laddress,Fname);
                dwValueA += 4;
            }

            dwValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );

     }

     // call the entry point :: here we assume that everything is ok.
     ((void(*)(void))EntryAddr)();

}    

但是当我将此代码用作 Release-x64 并将 test_x64.exe 作为文件时,我在此行中遇到访问冲突:

// get the VA    
dwValueC = (DWORD)(nt->OptionalHeader.ImageBase) + ((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress;

我不知道为什么。

【问题讨论】:

  • 可能是某处未定义的行为。你真的应该使用调试器来查明这个 UB。
  • 您的代码缺少错误和范围检查。
  • 由于您的代码行包含对成员、演员表和附加项的访问权限,您可以使用辅助变量拆分单个步骤以进一步定位您的问题。
  • 我不知道为什么。 -- 为什么不简单地将这个语句分成两部分,看看值是什么?我不明白为什么张贴者不做最起码的调试或检查。
  • 内存执行是特定于实现的(可能是编译器和操作系统特定的)。

标签: c++ in-memory


【解决方案1】:

这可能是 x64 指针不是 DWORD 大小:

DWORD dwValueB;
...
dwValueB = (DWORD) &(nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);

在我的minwindef.h 我有:

typedef unsigned long       DWORD;

sizeof(DWORD) 给我 4,但sizeof(void*) 给我 8。

【讨论】:

    猜你喜欢
    • 2021-02-09
    • 2018-09-17
    • 2017-12-09
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 2011-12-31
    • 1970-01-01
    相关资源
    最近更新 更多