重写一段已编译的 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();
}
这样做我能够先解密段然后执行函数。
我有一个这样构造的 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();
}
这样做我能够先解密段然后执行函数。