A esconder o código Python?
print "hello World !"
Como posso codificar este exemplo para que não seja legível por humanos? Disseram-me para usar base64, mas não sei como.
18 answers
Esta é apenas uma solução de ofuscação de primeiro nível limitada, mas está incorporada: Python tem um compilador para byte-code:
python -OO -m py_compile <your program.py>
Produz um ficheiro .pyo
que contém o código byte, e onde os documentos são removidos, etc. Pode mudar o nome do ficheiro .pyo
com uma extensão .py
, e python <your program.py>
corre como o seu programa, mas não contém o seu código-fonte.
PS : o nível "limitado" de ofuscação que você tem é tal que se pode recuperar o código (com alguns dos nomes de variáveis, mas sem comentários e documentos). Veja o primeiro comentário, para saber como fazê-lo. No entanto, em alguns casos, este nível de ofuscação pode ser considerado suficiente.
PPS : Se o seu programa importar módulos ofuscados desta forma, então terá de os renomear com um sufixo .pyc
em vez disso (Não tenho a certeza de que isto não irá quebrar um dia), ou poderá trabalhar com o .pyo
e executá-los com python -O ….pyo
(as importações deverão funcionar). Isto permitirá ao Python encontrar os seus módulos (caso contrário, O Python procura por módulos .py
.
Então, não é legível para os humanos? Quero dizer, todo o ficheiro está codificado !! quando a abres, não consegues perceber nada .. ! é isso que eu quero
Como máximo, você pode compilar as suas fontes em bytecode e depois distribuir apenas bytecode. Mas mesmo isto é reversível. Bytecode pode ser decompilado em fontes semi-legíveis.
O Base64 é trivial de descodificar para qualquer um, por isso não pode servir como protecção real e só irá esconder Fontes Do completo. PC analfabetos. Além disso, se você planeja realmente executar esse código por qualquer meio, você teria que incluir o decodificador direito no script (ou outro script em sua distribuição, que precisaria ser executado pelo usuário legítimo), e isso daria imediatamente a sua codificação/criptografia.As técnicas de ofuscação normalmente envolvem comentários/depilação de documentos, mutilação de nomes, inserção de códigos de lixo, e assim por diante, por isso mesmo que você descompile bytecode, você não obtém fontes muito legíveis. Mas serão. No entanto, o Python não é bom em se tornar uma bagunça ilegível.
Se você precisa absolutamente proteger alguma funcionalidade, eu sugeriria ir com linguagens compiladas, como C ou C++, compilando e distribuindo .so/.dll, e então usando ligações Python para código protegido.
Podes usar o base64
Módulo para codificar cordas para parar de surfar no ombro, mas não vai impedir que alguém encontre o seu código se tiver acesso aos seus ficheiros.
Pode então utilizar o compile()
função e eval()
função para executar o seu código depois de o descodificar.
>>> import base64
>>> mycode = "print 'Hello World!'"
>>> secret = base64.b64encode(mycode)
>>> secret
'cHJpbnQgJ2hlbGxvIFdvcmxkICEn'
>>> mydecode = base64.b64decode(secret)
>>> eval(compile(mydecode,'<string>','exec'))
Hello World!
Então se você tem 30 linhas de código você provavelmente vai querer criptografá-lo fazendo algo assim:
>>> f = open('myscript.py')
>>> encoded = base64.b64encode(f.read())
Então precisarias de escrever um o segundo programa que faz o compile()
e eval()
que provavelmente incluiria o programa codificado como um texto literal encapsulado em aspas triplas. Então, seria algo parecido com isto:
import base64
myscript = """IyBUaGlzIGlzIGEgc2FtcGxlIFB5d
GhvbiBzY3JpcHQKcHJpbnQgIkhlbG
xvIiwKcHJpbnQgIldvcmxkISIK"""
eval(compile(base64.b64decode(myscript),'<string>','exec'))
Bem, se queres fazer um código semi-ofuscado, fazes um código como este:
import zlib, base64
def run(code):
exec(zlib.decompress(base64.b16decode(code)))
def enc(code):
return base64.b16encode(zlib.compress(code))
E fazer um ficheiro como este (usando o código acima):
f = open('something.py','w')
f.write("code=" + enc("""
print("test program")
print(raw_input("> "))"""))
f.close()
Ficheiro "something.py":
code = '789CE352008282A2CCBC120DA592D4E212203B3FBD28315749930B215394581E9F9957500A5463A7A0A4A90900ADFB0FF9'
Apenas importa .something.py " e executar run(something.code)
para executar o código no arquivo.
Um truque é tornar o código difícil de ler por design: nunca documentar nada, se for preciso, basta dar a saída de uma função, não como ela funciona. Fazer nomes de variáveis muito amplos, referências de filmes, ou exemplos opostos: btmnsfavclr = 16777215
onde como "btmnsfavclr
"significa" cor favorita do Batman "e o valor é 16777215
ou a forma decimal de" ffffff
" ou branco. Lembre-se de misturar diferentes estilos de nomear para manter essas pessoas chatas de seu código. Além disso, use dicas neste site: Top 11 Dicas para desenvolver código Não-possível .
Pode incorporar o seu código e compilar/executar a partir de um programa C/C++. incorporar o Python noutra aplicação
Embutido.c
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("print('Hello world !')");
Py_Finalize();
return 0;
}
No ubuntu, debian
$ sudo apt-get install python-dev
Em centos, redhat, fedora
$ sudo yum install python-devel
Compila com
$ gcc -o embedded -fPIC -I/usr/include/python2.7 -lpython2.7 ./embedded.c
Corre com
$ chmod u+x ./embedded
$ time ./embedded
Hello world !
real 0m0.014s
user 0m0.008s
sys 0m0.004s
Hello_world.py:
print('Hello World !')
Executa o programa em python
$ time python hello_world.py
Hello World !
real 0m0.014s
user 0m0.008s
sys 0m0.004s
No entanto, algumas cadeias de caracteres do código python podem ser encontradas no compilado .c ficheiro
$ grep "Hello" ./embedded
Binary file ./embedded matches
$ grep "Hello World" ./embedded
$
No caso de quereres um pouco de segurança extra, podes usar o base64 no teu código
...
PyRun_SimpleString("import base64\n"
"base64_code = 'your python code in base64'\n"
"code = base64.b64decode(base64_code)\n"
"exec(code)");
...
E. g:
Cria a sequência de base 64 do teu código
$ base64 hello_world.py
cHJpbnQoJ0hlbGxvIFdvcmxkICEnKQoK
Embedded_base64.c
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("import base64\n"
"base64_code = 'cHJpbnQoJ0hlbGxvIFdvcmxkICEnKQoK'\n"
"code = base64.b64decode(base64_code)\n"
"exec(code)\n");
Py_Finalize();
return 0;
}
Todos os comandos
$ gcc -o embedded_base64 -fPIC -I/usr/include/python2.7 -lpython2.7 ./embedded_base64.c
$ chmod u+x ./embedded_base64
$ time ./embedded_base64
Hello World !
real 0m0.014s
user 0m0.008s
sys 0m0.004s
$ grep "Hello" ./embedded_base64
$
Encriptar .pyc
para .pye
e descodificar quando importar
Encriptar e descodificar por openaes da biblioteca
Utilização
Completo encriptado
-
Converter todos os seus
.py
para*.pye
$ pyconcrete-admin.py compile --source={your py script} --pye $ pyconcrete-admin.py compile --source={your py module dir} --pye
Remover
*.py
*.pyc
ou copiar*.pye
para outra pasta-
principal . py encriptado como principal .pye, não pode ser executado pelo normal. Deve utilizar
pyconcrete
para processar o principal .guião de pye.pyconcrete
(o exe será instalado na localização do seu sistema (ex: /usr/local/bin)pyconcrete main.pye src/*.pye # your libs
Parcialmente encriptado (pyconcrete como lib)
-
Transferir a fonte pyconcrete e instalar por setup.py
$ python setup.py install \ --install-lib={your project path} \ --install-scripts={where you want to execute pyconcrete-admin.py and pyconcrete(exe)}
Importar o pyconcrete no seu programa principal
-
Esquema do projecto de recomendação
main.py # import pyconcrete and your lib pyconcrete/* # put pyconcrete lib in project root, keep it as original files src/*.pye # your libs
A realidade é que Python não é a linguagem certa para usar se você quiser ofuscar o código. este posting tem algumas discussões excelentes sobre este mesmo ponto.
def MakeSC():
c = raw_input(" Encode: ")
sc = "\\x" + "\\x".join("{0:x}".format(ord(c)) for c in c)
print "\n shellcode =('" + sc + "'); exec(shellcode)"; MakeSC();
Cleartext:
import os; os.system("whoami")
Codificado:
Payload = ('\x69\x6d\x70\x6f\x72\x74\x20\x6f\x73\x3b\x20\x6f\x73\x2e\x73\x79\x73\x74\x65\x6d\x28\x22\x77\x68\x6f\x61\x6d\x69\x22\x29'); exec(Payload);
Deparei-me recentemente com este blogpost: ofuscação de código em Python usando o ASTs onde o autor fala sobre ofuscação de ficheiro de código em python usando o módulo ast builtin. O binário compilado era para ser usado para o HitB CTF e, como tal, tinha rigorosos requisitos de ofuscação.
Desde que tenha acesso a nós AST individuais, usando esta abordagem permite-lhe efectuar modificações arbitrárias no ficheiro de código. Dependendo das transformações que você realiza, resultando o binário pode / não se comportar exatamente como a fonte não-ofuscada.
Talvez devas procurar usar algo simples como um truecrypt volume para armazenamento de código-fonte, pois isso parece ser uma preocupação tua. Você pode criar um arquivo criptografado em uma chave usb ou simplesmente criptografar o volume inteiro (desde que o código irá caber) para que você possa simplesmente levar a chave com você no final do dia.
Para compilar, você poderia então usar algo como PyInstaller ou py2exe a fim de criar um executável independente. Se realmente quisesses para ir a milha extra, olhe para um packer ou utilitário de compressão a fim de adicionar mais ofuscação. Se nenhuma destas opções for uma opção, você poderia pelo menos compilar o script em bytecode para que ele não seja imediatamente legível. Tenha em mente que estes métodos apenas irá atrasar alguém tentando depurar ou descompilar o seu programa.
Python foi feito para ser legível e compartilhável, não ofuscado. As decisões linguísticas sobre como o código deve ser formatado foram para promover a legibilidade entre diferentes autor.
Ofuscar o código python não combina com a linguagem. Reavaliar as suas razões para ofuscar o código.
Tenta este ofuscador python:
Pyob.oxyry.com Pyob.oxyry.c
__all__ = ['foo']
a = 'a'
_b = 'b'
def foo():
print(a)
def bar():
print(_b)
def _baz():
print(a + _b)
foo()
bar()
_baz()
Will translated to
__all__ =['foo']#line:1
OO00OO0OO0O00O0OO ='a'#line:3
_O00OO0000OO0O0O0O ='b'#line:4
def foo ():#line:6
print (OO00OO0OO0O00O0OO )#line:7
def O0000000OOOO00OO0 ():#line:9
print (_O00OO0000OO0O0O0O )#line:10
def _OOO00000O000O0OOO ():#line:12
print (OO00OO0OO0O00O0OO +_O00OO0000OO0O0O0O )#line:13
foo ()#line:15
O0000000OOOO00OO0 ()#line:16
_OOO00000O000O0OOO ()#line:17
Isto é (como foi postado anteriormente) quase completamente inútil, mas se você realmente quiser, você pode usar codificação alternativa, como say ROT13 .
Primeiro tipo no seu interpretador de Python:
import this
Então, vá e dê uma olhada no Arquivo {[[2]} em seu diretório Lib dentro de sua distribuição Python e tente entender o que ele faz.
Depois disso, dê uma olhada na função eval
na documentação:
help(eval)
Devias ter encontrado uma maneira engraçada de proteger o teu código. Mas cuidado, porque isso só funciona para pessoas que são menos inteligentes do que tu! (e eu não estou tentando ser ofensivo, qualquer um inteligente o suficiente para entender o que você fez poderia revertê-lo).
Tente colar o seu código Python hello world no seguinte site:
Http://enscryption.com/encrypt-and-obfuscate-scripts.html
Vai produzir um script complexo criptografado e ofuscado, mas totalmente funcional para você. Vê se consegues decifrar o guião e revelar o código verdadeiro. Ou ver se o nível de complexidade que proporciona satisfaz a sua necessidade de paz de espírito. O script criptografado que é produzido para você através deste site deve funcionar em qualquer Sistema Unix que tem python instalado.Se quiser cifrar de outra forma, sugiro fortemente que escreva o seu próprio algoritmo de encriptação / ofuscação (se a segurança é assim tão importante para si) . Assim, ninguém consegue descobrir como funciona a não ser tu. Mas, para que isso realmente funcione, você tem que gastar uma quantidade tremenda de tempo nele para garantir que não há nenhuma lacuna que alguém que tem muito tempo em suas mãos pode explorar. E certifique-se de usar ferramentas que já estão natural para o sistema Unix... ou seja, openssl ou base64. Assim, o teu script encriptado é mais portátil.
Existem 2 formas de ofuscar os programas python
- ofuscar o código de bytes de cada objecto de código
- ofuscar todo o objecto de código do módulo python
Ofuscar Scripts Em Python
-
Compile python source file to code object
char * filename = "xxx.py"; char * source = read_file( filename ); PyObject *co = Py_CompileString( source, filename, Py_file_input );
-
Iterate code object, wrap bytecode of each code object as the following format
0 JUMP_ABSOLUTE n = 3 + len(bytecode) 3 ... ... Here it's obfuscated bytecode ... n LOAD_GLOBAL ? (__armor__) n+3 CALL_FUNCTION 0 n+6 POP_TOP n+7 JUMP_ABSOLUTE 0
-
Serializar o objecto do código e ofuscar it
char *original_code = marshal.dumps( co ); char *obfuscated_code = obfuscate_algorithm( original_code );
-
Criar script de embrulho "xxx.py", ${obfuscated_code} representa a constante de texto gerada na etapa anterior.
__pyarmor__(__name__, b'${obfuscated_code}')
Executar ou importar programas em Python ofuscados
Quando importar ou executar este script wrapper, a primeira declaração é chamar uma CFunction:
int __pyarmor__(char *name, unsigned char *obfuscated_code)
{
char *original_code = resotre_obfuscated_code( obfuscated_code );
PyObject *co = marshal.loads( original_code );
PyObject *mod = PyImport_ExecCodeModule( name, co );
}
Esta função Aceita 2 parâmetros: nome do módulo e código ofuscado, depois
- restaurar código ofuscado
- criar um objecto de código por código original
- importar o módulo original (isto irá resultar numa imagem duplicada em Traceback)
Run or Import Ofuscated Bytecode
Depois do módulo importado, quando qualquer objecto de código Neste módulo for chamado primeira vez, a partir do bytecode envolto na seção acima, nós sabe
O primeiro op é o JUMP_ absolute, irá saltar para o deslocamento n
Em offset n, a instrução é chamar uma função PyCFunction. Funcao poder restaurar os bytecodes ofuscados entre o offset 3 e n, e colocar o bytecode original na posição 0
Após a chamada de função, a última instrução é Saltar para deslocamento 0. O verdadeiro bytecode agora é executado.
Refere-se a Pyarmor
(lambda _, __, ___, ____, _____, ______, _______, ________:
getattr(
__import__(True.__class__.__name__[_] + [].__class__.__name__[__]),
().__class__.__eq__.__class__.__name__[:__] +
().__iter__().__class__.__name__[_____:________]
)(
_, (lambda _, __, ___: _(_, __, ___))(
lambda _, __, ___:
chr(___ % __) + _(_, __, ___ // __) if ___ else
(lambda: _).func_code.co_lnotab,
_ << ________,
(((_____ << ____) + _) << ((___ << _____) - ___)) + (((((___ << __)
- _) << ___) + _) << ((_____ << ____) + (_ << _))) + (((_______ <<
__) - _) << (((((_ << ___) + _)) << ___) + (_ << _))) + (((_______
<< ___) + _) << ((_ << ______) + _)) + (((_______ << ____) - _) <<
((_______ << ___))) + (((_ << ____) - _) << ((((___ << __) + _) <<
__) - _)) - (_______ << ((((___ << __) - _) << __) + _)) + (_______
<< (((((_ << ___) + _)) << __))) - ((((((_ << ___) + _)) << __) +
_) << ((((___ << __) + _) << _))) + (((_______ << __) - _) <<
(((((_ << ___) + _)) << _))) + (((___ << ___) + _) << ((_____ <<
_))) + (_____ << ______) + (_ << ___)
)
)
)(
*(lambda _, __, ___: _(_, __, ___))(
(lambda _, __, ___:
[__(___[(lambda: _).func_code.co_nlocals])] +
_(_, __, ___[(lambda _: _).func_code.co_nlocals:]) if ___ else []
),
lambda _: _.func_code.co_argcount,
(
lambda _: _,
lambda _, __: _,
lambda _, __, ___: _,
lambda _, __, ___, ____: _,
lambda _, __, ___, ____, _____: _,
lambda _, __, ___, ____, _____, ______: _,
lambda _, __, ___, ____, _____, ______, _______: _,
lambda _, __, ___, ____, _____, ______, _______, ________: _
)
)
)