1

暗号化されたプログラムがあるとしましょう。それを復号化ツールで開き、バイトを配列にロードして復号化します。

私が知りたいのは、別の実行可能ファイルを作成することなく、これらのバイトを実行する方法です。

「フォーク」を使用して可能であると読みましたが、それが最善の方法です。ただし、コードを正常に実行できず、エラーも返されません。これが私が得たもののサンプルです:

    //<main>
    char* lpMemory;
    lpMemory = (char*)malloc (fileSize);
    memset(lpMemory,0,fileSize);
    memcpy (lpMemory, fileBuf, fileSize);
    RunFromMemory(lpMemory, /* What here? */);

    //</main>

void RunFromMemory(char* pImage,char* pPath)
{
DWORD dwWritten = 0;
DWORD dwHeader = 0;
DWORD dwImageSize = 0;
DWORD dwSectionCount = 0;
DWORD dwSectionSize = 0;
DWORD firstSection = 0;
DWORD previousProtection = 0;
DWORD jmpSize = 0;

IMAGE_NT_HEADERS INH;
IMAGE_DOS_HEADER IDH;
IMAGE_SECTION_HEADER Sections[1000];

PROCESS_INFORMATION peProcessInformation;
STARTUPINFO peStartUpInformation;
CONTEXT pContext;

char* pMemory;
char* pFile;
memcpy(&IDH,pImage,sizeof(IDH));
memcpy(&INH,(void*)((DWORD)pImage+IDH.e_lfanew),sizeof(INH));

dwImageSize = INH.OptionalHeader.SizeOfImage;
pMemory = (char*)malloc(dwImageSize);
memset(pMemory,0,dwImageSize);
pFile = pMemory;

dwHeader = INH.OptionalHeader.SizeOfHeaders;
firstSection = (DWORD)(((DWORD)pImage+IDH.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
memcpy(Sections,(char*)(firstSection),sizeof(IMAGE_SECTION_HEADER)*INH.FileHeader.NumberOfSections);

memcpy(pFile,pImage,dwHeader);

if((INH.OptionalHeader.SizeOfHeaders % INH.OptionalHeader.SectionAlignment)==0)
{
    jmpSize = INH.OptionalHeader.SizeOfHeaders;
}
else
{
    jmpSize = INH.OptionalHeader.SizeOfHeaders / INH.OptionalHeader.SectionAlignment;
    jmpSize += 1;
    jmpSize *= INH.OptionalHeader.SectionAlignment;
}

pFile = (char*)((DWORD)pFile + jmpSize);

for(dwSectionCount = 0; dwSectionCount < INH.FileHeader.NumberOfSections; dwSectionCount++)
{
    jmpSize = 0;
    dwSectionSize = Sections[dwSectionCount].SizeOfRawData;
    memcpy(pFile,(char*)(pImage + Sections[dwSectionCount].PointerToRawData),dwSectionSize);

    if((Sections[dwSectionCount].Misc.VirtualSize % INH.OptionalHeader.SectionAlignment)==0)
    {
        jmpSize = Sections[dwSectionCount].Misc.VirtualSize;
    }
    else
    {
        jmpSize = Sections[dwSectionCount].Misc.VirtualSize / INH.OptionalHeader.SectionAlignment;
        jmpSize += 1;
        jmpSize *= INH.OptionalHeader.SectionAlignment;
    }
    pFile = (char*)((DWORD)pFile + jmpSize);
}


memset(&peStartUpInformation,0,sizeof(STARTUPINFO));
memset(&peProcessInformation,0,sizeof(PROCESS_INFORMATION));
memset(&pContext,0,sizeof(CONTEXT));

peStartUpInformation.cb = sizeof(peStartUpInformation);
if(CreateProcess(NULL, pPath, NULL /*&secAttrib*/, NULL,false,CREATE_SUSPENDED, NULL,NULL,&peStartUpInformation,&peProcessInformation))
{
    pContext.ContextFlags = CONTEXT_FULL;
    GetThreadContext(peProcessInformation.hThread,&pContext);
    VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,PAGE_EXECUTE_READWRITE,&previousProtection);
    WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),pMemory,dwImageSize,&dwWritten);
    WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)pContext.Ebx + 8),&INH.OptionalHeader.ImageBase,4,&dwWritten);
    pContext.Eax = INH.OptionalHeader.ImageBase + INH.OptionalHeader.AddressOfEntryPoint;
    SetThreadContext(peProcessInformation.hThread,&pContext);
    VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,previousProtection,0);
    ResumeThread(peProcessInformation.hThread);
}
free(pMemory);
}

ご想像のとおり、「fileSize」はプログラムのサイズで、「fileBuf」はバイト配列です。これらの値はどちらも正しいと確信しています。

私に役立つリソースへのリンクは大歓迎です。どうもありがとうございました。

4

2 に答える 2

1

配列内のバイトが実際に何を表しているかによっては、配列ポインターを関数ポインターに型キャストしてから、他のように「関数」を呼び出すことができる場合があります。これが機能するには、配列が実行可能メモリ (「参考文献」を参照VirtualProtect()) に常駐し、アセンブリ命令のバイト表現のみを含み、他には何も含まれていない必要があります。

于 2012-04-30T23:30:01.757 に答える
1

はい、可能です。バイト配列のポインターを関数ポインターにキャストし、それを呼び出した後に行う最も簡単な方法です。2 番目の方法は、インライン アセンブラを使用して、バイト配列のアドレスに対して jmp を実行することです。おそらく、配列が割り当てられているヒープまたはスタックは実行可能ではないため、VirtualProtect と関連する API ( win32 用) を使用する必要があります。

于 2012-04-30T23:30:14.553 に答える