重写一段已编译的 C 程序

Re-write segment of a compiled C program

我有一个这样构造的 C 程序:

#include <Windows.h>
#include <stdio.h>
#include <stdint.h>

#pragma section(".code",execute, read, write)
#pragma comment(linker,"/SECTION:.code,ERW")
#pragma code_seg(".code")

//Code to decrypt

#pragma section(".stub", execute, read, write)
#pragma code_seg(".stub")

void decryptor(){
    //Retrieve virtual address of the pointer to the .code section
    //Retrieve the virtual size of the pointer to the .code section
    for(int i = 0; i<size; i++){
         //HERE THE PROGRAM STOPS
         ptrCode[0] = //Reverse function of the encryptor
    }
}

int main(){
    decryptor();
    mainFunctionDecrypted();
    return 0;
}

基本上我有一个加密器,它在编译后首先加密这个程序的 exe 中的 .code 段。 然后,当我执行修改后的 exe 时,我希望能够先解密它,然后执行解密的部分。然而,我似乎无法写入内存中加载的 .code 段(我认为是因为它是专用于要执行的代码的部分内存)。

有没有办法写入可执行内存?

你有什么解决方法吗?

Windows 和其他操作系统竭尽全力阻止您这样做(修改 运行 应用程序的代码部分)。

那么,您的直接选择是

1) 将代码解密到为此目的动态分配的其他内存区域(然后代码必须仅使用与位置无关的指令,或者包含对具有特定位置数据的指令的自定义修正)。

2) 使用单独的程序在执行之前解密磁盘上的程序。

以这种方式混淆程序本质上是徒劳的。无论您的 "decryptor" 做什么,决心对您的程序进行逆向工程的人也可以做到。把你的精力花在让你的程序足够令人满意,以至于人们 想要 为它付钱,并且足够仁慈,以至于你不必隐藏它在做什么。

我需要按照以下方式修改代码。此外,在 visual studio 中还有一些重要的编译器选项需要设置,例如禁用数据执行保护。

使用的编译器选项: /permissive- /GS /TC /GL /analyze- /W3 /Gy /Zc:wchar_t /Gm- /O2 /sdl /Zc:inline /fp:precise /Zp1 /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /GR- /Gd /Oy- /Oi /MD /FC /nologo /diagnostics:classic

使用的链接器选项: /MANIFEST /LTCG:增量 /NXCOMPAT:NO /DYNAMICBASE:NO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /FIXED /MACHINE:X86 /OPT:REF /SAFESEH /INCREMENTAL:NO /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /MAP /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1

#pragma section(".code", execute, read)
#pragma section(".codedata", read, write)
#pragma comment(linker,"/SECTION:.code,ERW")
#pragma comment(linker,"/SECTION:.codedata,ERW")
#pragma comment(linker, "/MERGE:.codedata=.code")

//All the following will go in code
#pragma code_seg(".code")
#pragma data_seg(".codedata")
#pragma const_seg(".codedata")

//CODE TO DECRYPT

// .stub SECTION
#pragma section(".stub", execute, read)
#pragma section(".stubdata", read, write)
#pragma comment(linker,"/SECTION:.stub,ERW")
#pragma comment(linker,"/SECTION:.stubdata,ERW")
#pragma comment(linker, "/MERGE:.stubdata=.stub")

//All the following will go in .stub segment
#pragma code_seg(".stub")
#pragma data_seg(".stubdata")
#pragma const_seg(".stubdata")

/*This function needs to be changed to whatever correspond to the decryption function of the encryotion function used by the encryptor*/
void decryptCodeSection(){

     //Retrieve virtual address of the pointer to the .code section
     //Retrieve the virtual size of the pointer to the .code section
     for(int i = 0; i<size; i++){
          //HERE THE PROGRAM STOPS
          ptrCode[0] = //Reverse function of the encryptor
      }

void main(int argc, char* argv[]){
    decryptor();
    mainFunctionDecrypted();
}

这样做我能够先解密段然后执行函数。