我有一个以这种方式构建的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)使用一个单独的程序,在程序执行之前解密该程序。
以这种方式模糊程序本身就是徒劳的。无论你的“解密器”做什么,一个决心对你的程序进行逆向工程的人也可以这样做。花费你的努力,而不是让你的程序足够令人满意,以至于人们想要为你支付费用,而且要善于你不必隐藏它正在做的事情。
我需要以下面的方式修改代码。此外,在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:incremental / 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();
}
这样做我能够首先解密段然后执行该功能。