#include <stdio.h>
#include <windows.h>
#include "_CSD.h"
int f(char * t) {
printf(_C("|t:%s| "),t);
return 0;
}
int main(int argc, char ** argv) {
f(_C("testing"));
f(_C("test2"));
return 1;
}
#include <windows.h>
#include "_CSD.h"
int f(char * t) {
printf(_C("|t:%s| "),t);
return 0;
}
int main(int argc, char ** argv) {
f(_C("testing"));
f(_C("test2"));
return 1;
}
будет преобразован в следующий:
#include <stdio.h>
#include <windows.h>
#include "_CSD.h"
int f(char * t) {
printf(CSDecrypt("\x00\xf2\xfb\xaa\xb4\xe1\xef\xb4",7,142),t);
return 0;
}
int main(int argc, char ** argv) {
f(CSDecrypt("\x00\xe7\xf1\xe6\xe2\xfe\xf6\xfe",7,147));
f(CSDecrypt("\x00\x14\x04\x11\x17\x56",5,96));
return 1;
}
#include <windows.h>
#include "_CSD.h"
int f(char * t) {
printf(CSDecrypt("\x00\xf2\xfb\xaa\xb4\xe1\xef\xb4",7,142),t);
return 0;
}
int main(int argc, char ** argv) {
f(CSDecrypt("\x00\xe7\xf1\xe6\xe2\xfe\xf6\xfe",7,147));
f(CSDecrypt("\x00\x14\x04\x11\x17\x56",5,96));
return 1;
}
_CSD.h содержит функцию расшифровки.
#pragma once
inline char* CSDecrypt(char *str, size_t len, BYTE key) {
char *flag = str;
str++;
if (*flag=='\x01') {
return str;
}
for (int i=0;i<len;i++) {
str[i]^=(key+i);
}
*flag = '\x01';
return str;
}
inline char* CSDecrypt(char *str, size_t len, BYTE key) {
char *flag = str;
str++;
if (*flag=='\x01') {
return str;
}
for (int i=0;i<len;i++) {
str[i]^=(key+i);
}
*flag = '\x01';
return str;
}
Желательно передать компилятору /Ob1, т.к. inline. И ещё, важный момент, память, в которай расположенна строка, должна быть доступна для записи, иначе будет исключение C0000005 (ACCESS VIOLATION).
вот сам код "препроцессора":
import sys, re
from random import randint
def XorStr(str,key):
retval = ""
for i in range(0,len(str)):
t = ord(str[i])^int(key+i)
retval += chr(t)
return retval
def FmtXorStr(str):
retval = r"\x00"
for x in str:
retval += r"\x%02x" % ord(x)
return retval
def _C(obj):
key = randint(1,254)
str = XorStr(obj.group(1),key)
retval = 'CSDecrypt("%s",%d,%d)' % (FmtXorStr(str),len(obj.group(1)),key)
return retval
def main():
try:
f = open(sys.argv[1],"r")
code = f.read()
f.close()
dest = open(sys.argv[2],"w")
except:
print "%s <in> <out>" % sys.argv[0]
return 0
r = re.sub(r'_C\("(.*?)"\)',_C,code)
dest.write(r)
dest.close()
return 1
main()
from random import randint
def XorStr(str,key):
retval = ""
for i in range(0,len(str)):
t = ord(str[i])^int(key+i)
retval += chr(t)
return retval
def FmtXorStr(str):
retval = r"\x00"
for x in str:
retval += r"\x%02x" % ord(x)
return retval
def _C(obj):
key = randint(1,254)
str = XorStr(obj.group(1),key)
retval = 'CSDecrypt("%s",%d,%d)' % (FmtXorStr(str),len(obj.group(1)),key)
return retval
def main():
try:
f = open(sys.argv[1],"r")
code = f.read()
f.close()
dest = open(sys.argv[2],"w")
except:
print "%s <in> <out>" % sys.argv[0]
return 0
r = re.sub(r'_C\("(.*?)"\)',_C,code)
dest.write(r)
dest.close()
return 1
main()
Я сейчас почти полностью перешел на vim + scons. Вот пример как подключить "препроцессор" (pre.py) к scons:
env = Environment(
CCFLAGS = "/Ob1 /c /D_CSD",
LINKFLAGS = "/MERGE:.rdata=.text /MERGE:.data=.text /SECTION:.text,EWR"
)
PyPre = Builder(action = 'pre.py $SOURCE $TARGET',
src_suffix = '.cpp', suffix = '.cxx')
env["BUILDERS"]["PyPre"] = PyPre
for x in Glob("*.cpp"):
env.PyPre(x)
env.Program("test.exe",Glob("*.cxx"))
CCFLAGS = "/Ob1 /c /D_CSD",
LINKFLAGS = "/MERGE:.rdata=.text /MERGE:.data=.text /SECTION:.text,EWR"
)
PyPre = Builder(action = 'pre.py $SOURCE $TARGET',
src_suffix = '.cpp', suffix = '.cxx')
env["BUILDERS"]["PyPre"] = PyPre
for x in Glob("*.cpp"):
env.PyPre(x)
env.Program("test.exe",Glob("*.cxx"))
Конечно могут быть всякие баги-глюки, т.к. не особо тестилось всё это. Но осоновная идея я думаю понятна. Из известных недостатков:
1. Нельзя юзать так: char a[] = _C("test");
2. Не корректно обрабатываются спецсимволы ( например \n\r )
3. ...
UPD
проблема со спецсимволами решается через .decode("string_escape")