Necesitarás Python.
Para instalarla en tu proyecto debes de editar el fichero de proyecto (.vcxproj en el caso de VC) añadiendo este código XML:
Código
Obviamente la ruta hay que cambiarla para que apunte al fichero .targets que aquí adjunto:
<Import Project="C:\Users\Karcrack\Desktop\kPreprocessor\kPreprocessor.targets" />
Código
En este fichero hay que cambiar las rutas para que apunten a este fichero .py:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="OutDir"> <Target Name="kPreprocessor" BeforeTargets="CLCompile"> <Exec Command='python "C:\Users\Karcrack\Desktop\kPreprocessor\kPreprocessor.py" %(CLInclude.FullPath) %(CLCompile.FullPath)' /> </Target> <Target Name="kCleanPreProc" AfterTargets="Link"> <Exec Command='python "C:\Users\Karcrack\Desktop\kPreprocessor\kPreprocessor.py" -clean' /> </Target> </Project>
Código
# -*- coding: utf8 -*- from sys import argv from shutil import copyfile import os, re def save2dump(s): f = open("./dump","a") f.write(s) f.close() if __name__ == "__main__": if argv[1] == "-clean": print "[kP] Limpiando y restaurando ficheros." for file_name in os.listdir("./"): root, ext = os.path.splitext(file_name) if ext == ".kbak": os.remove(os.path.join("./", root)) os.rename(os.path.join("./", file_name), os.path.join("./", root)) os.remove("./dump") else: file_path = argv[1] print "[kP] Trabajando sobre el fichero '%s'" % (file_path) #Backup copyfile(file_path, file_path+".kbak") #Read SRC with open(file_path, "r") as r: raw = r.read() #INCLUDE_PYSRC() for i in re.findall("(?<=INCLUDE_PYSRC\()(.*?)(?=\)\n)", raw, re.DOTALL): with open(os.path.abspath(i), 'r') as fi: save2dump(fi.read()+"\n") #DEFINE_PYSRC() r = re.findall("(?<=DEFINE_PYSRC\(\n)(.*?)(?=\)DEFINE_END\(\))", raw, re.DOTALL) if len(r)>0: save2dump(''.join(r) + "\n") #Load src try: exec open("./dump", "r") except IOError as e: pass #Resolve macros for fu in re.findall("(?<=#define)(.*?)(?=\(\.\.\.\) *PYTHON_FUNCTION\(\))", raw, re.DOTALL): raw = re.sub("("+fu+"\([^\.?].*?\)(?=[^\:]))", lambda m:str(eval(m.group(1))), raw) #Save file with open(file_path, "w+") as f: f.write(raw)
Después de la instalación podéis hacer cosas como ésta:
Header.h:
Código
Main.cpp:
#ifndef PRETEST #define PRETEST #include <Windows.h> #include "../../kPreprocessor/kPreprocessor.h" INCLUDE_PYSRC(.\test.py) DEFINE_PYSRC( def TEST(): return 12 )DEFINE_END() #endif
Código
test.py:
#pragma comment(linker, "/ENTRY:main") #include "Header.h" #define XOR_STR(...) PYTHON_FUNCTION() #define MD5(...) PYTHON_FUNCTION() #define TEST(...) PYTHON_FUNCTION() void main(){ MessageBoxA(0, XOR_STR("karcrack", 0xFF), MD5("karcrack"), TEST( )); }
Código:
#Glenn Maynard
def string_to_c(s, max_length = 140, unicode=False):
ret = []
# Try to split on whitespace, not in the middle of a word.
split_at_space_pos = max_length - 10
if split_at_space_pos < 10:
split_at_space_pos = None
position = 0
if unicode:
position += 1
ret.append('L')
ret.append('"')
position += 1
for c in s:
newline = False
if c == "\n":
to_add = "\\\n"
newline = True
elif ord(c) < 32 or 0x80 <= ord(c) <= 0xff:
to_add = "\\x%02x" % ord(c)
elif ord(c) > 0xff:
if not unicode:
raise ValueError, "string contains unicode character but unicode=False"
to_add = "\\u%04x" % ord(c)
elif "\\\"".find(c) != -1:
to_add = "\\%c" % c
else:
to_add = c
ret.append(to_add)
position += len(to_add)
if newline:
position = 0
if split_at_space_pos is not None and position >= split_at_space_pos and " \t".find(c) != -1:
ret.append("\\\n")
position = 0
elif position >= max_length:
ret.append("\\\n")
position = 0
ret.append('"')
return "".join(ret)
def XOR_STR(str, c):
s = ""
for x in str:
s+= chr(ord(x)^c)
return string_to_c(s)
def MD5(s):
import md5
return string_to_c(md5.new(s).hexdigest())
Hay errores en la detección de tokens ya que se hace con expresiones regulares algo chapuzas
Todavía sigo trabajando en esto, así que seguid atentos para mejoras y arreglo de errores... y una explicación más elaborada en cuanto tenga tiempo xD
Nota: No se expandirán macros originales (C/C++ es en ejemplo) en la llamada a funciones. [Debido al diseño, no será reparado]
Saludos