Facilitador de conversão de C/C++ para Assembly para usar em CLEO/SCM
Enviado: 13 Set 2018, 11:21

Este programa ajuda com a compilação e preparação do código C/C++ compilado para usar em um script CLEO/SCM.
Estou aproveitando o conteúdo do tópico da BMS, talvez faça alterações futuras ou reescreva tudo.
Versão 1.0:
SpoilerAbrir
OBS: Outros compiladores ou montadores assembly podem não ser compatíveis com o programa.
Ter noção do funcionamento do básico e de como usar o IDA é necessário: http://bms.mixmods.com.br/t5034-x-engen ... rsa-basico
Vou fazer apenas uma apresentação superficial de como usar a ferramenta e fazer os códigos, portanto é necessário um bom conhecimento do funcionamento de gta3script e C++ previamente.
Por favor leia todos os tutoriais antes de prosseguir: http://bms.mixmods.com.br/t203-indice-d ... script-scm http://bms.mixmods.com.br/t5967-indice- ... gta3script
http://en.cppreference.com/book/
Nessa versão do programa eu criei dois arquivos headers, um para ser usado no topo do código, outro para ser usado no fim do código. Essas headers cuidarão da inicialização de construtores, referências para o software e correção de endereços globais.
Outra novidade é o SymbolList.txt, nele pode ser colocado funções e seus endereços, podem ser copiadas direto da function list do IDA, pelo método de selecionar, copiar e colar.
Como eu fiz para já receber uma lista pronta facilmente, cada função deve estar em uma linha separada e da seguinte forma:
O underline no inicio da função é necessário, pois o nome das funções compiladas ganham um underline (_).
Exemplo do protótipo da função generateLicenseplate dentro do código:
Dentro do SymbolList.txt ela deverá ser:
O software gerará dentro do código final apenas as funções necessárias, portanto pode ter uma lista imensa.
Arquivo de exemplo:
Tanto esse código de exemplo quanto o top.h e btn.h estão incluídos no download.
Exemplo de uso do código acima dentro de um script de gta3script:
Conteúdo antigo do tópicoAbrir
Inicialmente, para que serve?
Para facilitar a compilação de códigos de C++ e usá-los em scripts CLEO/SCM, exemplo, eu tenho o seguinte código:
Eu preciso colocá-lo em um script para usar no GTA, para fazer manualmente da maneira mais fácil eu preciso usar o MinGW, pegar o output assembly e usar o NASM em seguida para gerar meu binário, o problema é que o NASM não gera apenas o código hex legivel por humanos, mas a quantidade de linhas, etc. coisa que não posso colocar no hex...end do sanny builder, então ou eu preciso comentar esse código, ou eu apago, mas como é uma utilidade para a localização de offsets, linhas, etc. é bom deixar. O problema de tudo isso é você precisar ficar alterando seu código C++ e toda hora você precisar repetir a tarefa de comentar o seu hex de assembly, é isso que o programa faz, você coloca o input .CPP nele, ele faz todas as adaptações de sintaxe e te devolve o output.asm.txt pronto para usar no sanny builder, assim:

Pré requisitos:
Antes de começar você precisa colocar o path do NASM e do MinGW corretamente no Config.txt, não é necessário mexer nos nomes de output e nos parâmetros
Atualização:
Geração de código binário pronto para usar com C++
Para facilitar a compilação de códigos de C++ e usá-los em scripts CLEO/SCM, exemplo, eu tenho o seguinte código:
Código: Selecionar tudo
#include <cstdint>
void decriptMyScript(int *start, int *end){
int password = 0xFFFFFFFF;
for(int64_t i = 0, size = (end - start + 4) / 4; i < size; i++){
start[i] ^= password;
password = start[i];
}
}
Eu preciso colocá-lo em um script para usar no GTA, para fazer manualmente da maneira mais fácil eu preciso usar o MinGW, pegar o output assembly e usar o NASM em seguida para gerar meu binário, o problema é que o NASM não gera apenas o código hex legivel por humanos, mas a quantidade de linhas, etc. coisa que não posso colocar no hex...end do sanny builder, então ou eu preciso comentar esse código, ou eu apago, mas como é uma utilidade para a localização de offsets, linhas, etc. é bom deixar. O problema de tudo isso é você precisar ficar alterando seu código C++ e toda hora você precisar repetir a tarefa de comentar o seu hex de assembly, é isso que o programa faz, você coloca o input .CPP nele, ele faz todas as adaptações de sintaxe e te devolve o output.asm.txt pronto para usar no sanny builder, assim:
Código: Selecionar tudo
hex
// 1 BITS 32
// 2
// 3 ;.file "dec.cpp"
// 4 ;.intel_syntax noprefix
// 5 ;.text
// 6 ;.globl __Z15decriptMyScriptPiS_
// 7 ;.def __Z15decriptMyScriptPiS_; ;.scl 2; ;.type 32; ;.endef
// 8 __Z15decriptMyScriptPiS_:
// 9 LFB0:
// 10 ;.cfi_startproc
{ 11 00000000} 55 //push ebp
// 12 ;.cfi_def_cfa_offset 8
// 13 ;.cfi_offset 5, -8
{ 14 00000001} 89E5 //mov ebp, esp
// 15 ;.cfi_def_cfa_register 5
{ 16 00000003} 81EC20000000 //sub esp, 32
{ 17 00000009} C745FCFFFFFFFF //mov DWORD [ebp-4], -1
{ 18 00000010} C745F000000000 //mov DWORD [ebp-16], 0
{ 19 00000017} C745F400000000 //mov DWORD [ebp-12], 0
{ 20 0000001E} 8B550C //mov edx, DWORD [ebp+12]
{ 21 00000021} 8B4508 //mov eax, DWORD [ebp+8]
{ 22 00000024} 29C2 //sub edx, eax
{ 23 00000026} 89D0 //mov eax, edx
{ 24 00000028} C1F802 //sar eax, 2
{ 25 0000002B} 0504000000 //add eax, 4
{ 26 00000030} 8D5003 //lea edx, [eax+3]
{ 27 00000033} 85C0 //test eax, eax
{ 28 00000035} 0F48C2 //cmovs eax, edx
{ 29 00000038} C1F802 //sar eax, 2
{ 30 0000003B} 99 //cdq
{ 31 0000003C} 8945E8 //mov DWORD [ebp-24], eax
{ 32 0000003F} 8955EC //mov DWORD [ebp-20], edx
{ 33 00000042} E947000000 //jmp L2
// 34 L3:
{ 35 00000047} 8B45F0 //mov eax, DWORD [ebp-16]
{ 36 0000004A} 8D148500000000 //lea edx, [0+eax*4]
{ 37 00000051} 8B4508 //mov eax, DWORD [ebp+8]
{ 38 00000054} 01C2 //add edx, eax
{ 39 00000056} 8B45F0 //mov eax, DWORD [ebp-16]
{ 40 00000059} 8D0C8500000000 //lea ecx, [0+eax*4]
{ 41 00000060} 8B4508 //mov eax, DWORD [ebp+8]
{ 42 00000063} 01C8 //add eax, ecx
{ 43 00000065} 8B00 //mov eax, DWORD [eax]
{ 44 00000067} 3345FC //xor eax, DWORD [ebp-4]
{ 45 0000006A} 8902 //mov DWORD [edx], eax
{ 46 0000006C} 8B45F0 //mov eax, DWORD [ebp-16]
{ 47 0000006F} 8D148500000000 //lea edx, [0+eax*4]
{ 48 00000076} 8B4508 //mov eax, DWORD [ebp+8]
{ 49 00000079} 01D0 //add eax, edx
{ 50 0000007B} 8B00 //mov eax, DWORD [eax]
{ 51 0000007D} 8945FC //mov DWORD [ebp-4], eax
{ 52 00000080} 8145F001000000 //add DWORD [ebp-16], 1
{ 53 00000087} 8155F400000000 //adc DWORD [ebp-12], 0
// 54 L2:
{ 55 0000008E} 8B45F0 //mov eax, DWORD [ebp-16]
{ 56 00000091} 8B55F4 //mov edx, DWORD [ebp-12]
{ 57 00000094} 3B55EC //cmp edx, DWORD [ebp-20]
{ 58 00000097} 7CAE //jl L3
{ 59 00000099} 3B55EC //cmp edx, DWORD [ebp-20]
{ 60 0000009C} 7F05 //jg L1
{ 61 0000009E} 3B45E8 //cmp eax, DWORD [ebp-24]
{ 62 000000A1} 72A4 //jb L3
// 63 L1:
{ 64 000000A3} C9 //leave
// 65 ;.cfi_restore 5
// 66 ;.cfi_def_cfa 4, 4
{ 67 000000A4} C3 //ret
// 68 ;.cfi_endproc
// 69 LFE0:
// 70 ;.ident "GCC: (GNU) 4.8.1"
end

Pré requisitos:
- MinGW
- NASM
Antes de começar você precisa colocar o path do NASM e do MinGW corretamente no Config.txt, não é necessário mexer nos nomes de output e nos parâmetros
Atualização:
Geração de código binário pronto para usar com C++
Código: Selecionar tudo
char code[] = {bytes do script aqui};Ter noção do funcionamento do básico e de como usar o IDA é necessário: http://bms.mixmods.com.br/t5034-x-engen ... rsa-basico
SpoilerAbrir
O programa está passando por melhorias, então algumas funções podem mudar ou serem trocadas por formas melhores.
Vou fazer apenas uma apresentação superficial de como usar a ferramenta e fazer os códigos, portanto é necessário um bom conhecimento do funcionamento de gta3script e C++ previamente.
Por favor leia todos os tutoriais antes de prosseguir: http://bms.mixmods.com.br/t203-indice-d ... script-scm http://bms.mixmods.com.br/t5967-indice- ... gta3script
http://en.cppreference.com/book/
Nessa versão do programa eu criei dois arquivos headers, um para ser usado no topo do código, outro para ser usado no fim do código. Essas headers cuidarão da inicialização de construtores, referências para o software e correção de endereços globais.
Outra novidade é o SymbolList.txt, nele pode ser colocado funções e seus endereços, podem ser copiadas direto da function list do IDA, pelo método de selecionar, copiar e colar.
Código: Selecionar tudo
_strlen .text 00826330 0000008B 00000000 00000004 R . L S . T .
_strcmp .text 008263C0 00000088 00000000 00000008 R . L S . T .
_strncat .text 00826450 00000135 00000000 0000000C R . L S . T .
_strcpy_0 .text 00826590 00000007 00000004 00000008 R . L . . T .
_strcat .text 008265A0 000000E8 00000000 00000008 R . L S . T .
_fclose .text 0082318B 00000046 00000000 00000000 R . L . . T .
_fcos .text 0041BCF0 00000007 00000000 00000004 R . . . . T .
_feof .text 008262A2 0000000B 00000000 00000004 R . . . . T .
_ferror .text 008262AD 0000000B 00000000 00000004 R . L . . T .
_fflush .text 00823E86 00000046 R . L . . T .
_fgetc .text 008231DC 00000045 R . L . . T .
_fgetc_0 .text 0082322C 00000045 R . L . . T .
_fgets .text 00823798 0000007B 00000000 00000000 R . L . . T .
_findAnimationStyleByBaseName .text 004D39B0 00000039 00000004 00000004 R . . . . T .
_findCrane .text 00556000 0000002F 00000004 00000004 R . . . . T .
_findCullZoneForPoint .text 0072DAD0 0000007B 0000000C 00000000 R . . . . . .
_findCullZoneReflectionForPoint .text 0072DA70 0000005E 00000010 0000000C R . . . . . .
_findFirstAtomicWith2dfx .text 00734880 00000025 00000004 00000004 R . . . . . .
_findFirstAtomicWith2dfxCB .text 00734850 00000022 00000000 00000008 R . . . . T .
_findFrameByNodeNameCB .text 004C52A0 00000045 00000004 00000008 R . . . . T .
_findIfpFileByName .text 004D3940 00000046 00000000 00000004 R . . . . . .
_findShoppingDatSection .text 0049AE70 0000009C 00000008 00000008 R . . . . T .
_findenv .text 00834F14 0000004D 00000004 00000004 R . L S . . .
_fix_grouping .text 0082FDD6 00000033 R . L S . . .
_fix_grouping_0 .text 00830035 00000033 R . L S . . .
_floor .text 008219F0 00000121 00000010 00000008 R . L . . T .
_floor_0 .text 00828A60 000000D1 00000028 00000008 R . L . B T .
_floor_1 .text 0082BA31 000000D1 00000028 00000008 R . L . B T .
_fopen .text 008232D8 00000013 00000000 00000008 R . L . . T .
_fpow .text 00470000 0000000E 00000000 00000008 R . . . . T .
_fprintf .text 00823A30 00000054 R . . . . T .
_fputs .text 008262B8 00000067 R . L . . T .
_frameFlattenHierarchyCB .text 004C8E30 00000030 00000004 00000008 R . . . . T .
_frameGetFirstChild .text 00734900 00000025 00000004 00000004 R . . . . T .
_frameGetHAnimHierarchy .text 00734AB0 00000056 00000008 00000004 R . . . . T .
_frameGetHAnimHierarchyCB .text 00734A70 00000033 00000004 00000008 R . . . . T .
_fread .text 00823521 00000042 00000000 00000010 R . L . . T .
_fread_0 .text 00823438 000000E9 0000000C 00000010 R . L . B T .
_free .text 0082413F 00000053 R . . . . T .
_freeCollisionFilePool .text 004114D0 000000A4 00000004 00000000 R . . . . . .
_freeCollisions .text 004162E0 00000044 00000004 00000000 R . . . . . .
_freeMapPipe .text 005DA130 000000F6 00000000 00000000 R . . . . . .
_freePaths .text 00459400 0000003C 00000008 00000000 R . . . . . .
_freePedAcquaintances .text 00608B00 00000029 R . . . . . .
_freezeVehicleOnPath .text 00459740 00000105 00000000 00000004 R . . . . . .
_fseek .text 0082374F 0000003F 00000000 00000000 R . L . . T .
_fsin .text 0041BCE0 00000007 00000000 00000004 R . . . . T .
_fsopen .text 0082327C 00000052 R . . . . T .
_ftell .text 00826261 00000037 R . L . . T .
_fwrite .text 00823674 00000042 00000000 00000000 R . L . . T .
_fwrite_0 .text 0082356D 00000107 0000000C 00000010 R . L . B T .
_generateLicenseplate .text 006FD5B0
Como eu fiz para já receber uma lista pronta facilmente, cada função deve estar em uma linha separada e da seguinte forma:
Código: Selecionar tudo
_generateLicenseplate .text 006FD5B0Código: Selecionar tudo
_NOMEDAFUNCAO .text ENDEREÇO EM HEXO underline no inicio da função é necessário, pois o nome das funções compiladas ganham um underline (_).
Exemplo do protótipo da função generateLicenseplate dentro do código:
Código: Selecionar tudo
extern "C" bool __cdecl generateLicenseplate(char *buf, signed int len);
Dentro do SymbolList.txt ela deverá ser:
Código: Selecionar tudo
_generateLicenseplate .text 006FD5B0O software gerará dentro do código final apenas as funções necessárias, portanto pode ter uma lista imensa.
Arquivo de exemplo:
Código: Selecionar tudo
/****************************************************************************
* http://bms.mixmods.com.br/t4721-avancado-facilitador-de-conversao-de-c-para-assembly-para-usar-em-scripts-cleo-scm
*
*
*/
#include "includes/top.h" // Esta header deverá ser incluída no topo, ao usar ela, incluir a btn.h também
#include <cstring> // Protótipos das funções de string de C, como por exemplo strcmp, entre outras.
///************************************ INÍCIO DO CÓDIGO CPP ********************************************************
// CLASSES!!!
class testClass
{
int a;
const char *strA;
public:
const char *getStrA()
{
return strA;
}
// Suporte a construtores
testClass() : strA("ABCDEF")
{
a = 10;
}
};
// OBJETO GLOBAL DA CLASSE, o Helper chamará o construtor da classe automaticamente
testClass b;
/// ATENÇÃO: Para que o código funcione adequadamente, deve ter um call para _initCPPCode,
/// feito apenas UMA ÚNICA VEZ, antes de chamar qualquer outra função do código.
/// Como demonstrado no código comentado abaixo:
/*
SCRIPT_START
{
LVAR_INT init main rtn
GET_LABEL_POINTER _initCPPCode init
GET_LABEL_POINTER _codeMain main
WAIT 0
CALL_FUNCTION init 0 0
ad_infinitum:
WAIT 5000
CALL_FUNCTION_RETURN main 1 1 (0) (rtn)
GOTO ad_infinitum
}
SCRIPT_END
*/
/* É bom usar extern "C" nessa função, para evitar que o compilador altere para um nome aleatório
* quando usar uma função codeMain, o Helper irá destacar a posição dela com um DUMP _codeMain: ENDDUMP
* para facilitar o uso com gta3script, pode ser usada no Sanny Builder também alterando DUMP para HEX e ENDDUMP para END
*/
extern "C" int __declspec(dllexport) codeMain(int i)
{
//showTextBox(b.getStrA(), 0, 0, 0);
char aaa[32] = {0};
// Testando a função do jogo prototipada no top.h e com endereço definido no SymbolList.txt
bool gerado = generateLicenseplate(aaa, 8);
if (strcmp("ABCDEF", b.getStrA()) == 0)
{
showTextBox(aaa, 0, 0, 0);
}
return 0;
}
///************************************ FINAL DO ARQUIVO CPP ********************************************************
#include "includes/btn.h" // Esta header deverá ser incluída no final do código, ao usar ela, incluir a top.h também
Exemplo de uso do código acima dentro de um script de gta3script:
Código: Selecionar tudo
SCRIPT_START
{
LVAR_INT init main rtn
GET_LABEL_POINTER _initCPPCode init
GET_LABEL_POINTER _codeMain main
WAIT 0
CALL_FUNCTION init 0 0
ad_infinitum:
WAIT 5000
CALL_FUNCTION_RETURN main 1 1 (0) (rtn)
GOTO ad_infinitum
}
SCRIPT_END
DUMP
// _topCPPCodeLabel:
// __ZStL19piecewise_construct:
/* 11 00000000*/ 00 //db00
// __ZStL13allocator_arg:
/* 13 00000001*/ 00 //db00
// __ZStL6ignore:
/* 15 00000002*/ 00 //db00
// _putNonDefinedSymbolsHere:
// _strcmp:
/* 20 00000003*/ B8C0638200 //moveax, 0x008263c0
/* 21 00000008*/ FFE0 //jmpeax
// _generateLicenseplate:
/* 24 0000000A*/ B8B0D56F00 //moveax, 0x006fd5b0
/* 25 0000000F*/ FFE0 //jmpeax
/* 27 00000011*/ 90 //nop
// 31 ;.data
// 32 ;.align 4
// _gtarand:
/* 34 00000012*/ 1E1B8200 //dd8526622
// 36 ;.align 4
// _showTextBox:
/* 38 00000016*/ E08B5800 //dd5802976
// 40 ;.align 4
// _gtastrncmp:
/* 42 0000001A*/ D0148200 //dd8525008
// 44 ;.align 4
// _gtasprintf:
/* 46 0000001E*/ B51B8200 //dd8526773
// 48 ;.linkonce discard
// 49 ;.align 2
// __ZN9testClass7getStrAEv:
// LFB2675:
/* 55 00000022*/ 55 //push ebp
/* 58 00000023*/ 89E5 //mov ebp, esp
/* 60 00000025*/ 83EC04 //sub esp, 4
/* 61 00000028*/ 894DFC //mov DWORD [ebp-4], ecx
/* 62 0000002B*/ 8B45FC //mov eax, DWORD [ebp-4]
/* 63 0000002E*/ 8B4004 //mov eax, DWORD [eax+4]
/* 64 00000031*/ C9 //leave
/* 67 00000032*/ C3 //ret
// LFE2675:
// LC0:
/* 72 00000033*/ 41424344454600 //db'ABCDEF', 00
// 74 ;.linkonce discard
// 75 ;.align 2
// __ZN9testClassC1Ev:
// LFB2678:
/* 81 0000003A*/ 55 //push ebp
/* 84 0000003B*/ 89E5 //mov ebp, esp
/* 86 0000003D*/ 83EC04 //sub esp, 4
/* 87 00000040*/ 894DFC //mov DWORD [ebp-4], ecx
/* 88 00000043*/ 8B45FC //mov eax, DWORD [ebp-4]
/* 89 00000046*/ C7400433000000 //mov DWORD eax+4, LC0
/* 90 0000004D*/ 8B45FC //mov eax, DWORD [ebp-4]
/* 91 00000050*/ C7000A000000 //mov DWORD [eax], 10
/* 92 00000056*/ C9 //leave
/* 95 00000057*/ C3 //ret
// LFE2678:
// 100 ;.align 4
// _b:
/* 102 00000058*/ 0000000000000000 //db00,00,00,00,00,00,00,00
ENDDUMP
_codeMain:
DUMP
// LFB2679:
/* 109 00000060*/ 55 //push ebp
/* 112 00000061*/ 89E5 //mov ebp, esp
/* 114 00000063*/ 56 //push esi
/* 115 00000064*/ 53 //push ebx
/* 116 00000065*/ 83EC40 //sub esp, 64
/* 119 00000068*/ 8D45D7 //lea eax, [ebp-41]
/* 120 0000006B*/ BA20000000 //mov edx, 32
/* 121 00000070*/ B900000000 //mov ecx, 0
/* 122 00000075*/ 89C3 //mov ebx, eax
/* 123 00000077*/ 83E301 //and ebx, 1
/* 124 0000007A*/ 85DB //test ebx, ebx
/* 125 0000007C*/ 7408 //je L5
/* 126 0000007E*/ 8808 //mov BYTE [eax], cl
/* 127 00000080*/ 83C001 //add eax, 1
/* 128 00000083*/ 83EA01 //sub edx, 1
// L5:
/* 130 00000086*/ 89C3 //mov ebx, eax
/* 131 00000088*/ 83E302 //and ebx, 2
/* 132 0000008B*/ 85DB //test ebx, ebx
/* 133 0000008D*/ 7409 //je L6
/* 134 0000008F*/ 668908 //mov WORD [eax], cx
/* 135 00000092*/ 83C002 //add eax, 2
/* 136 00000095*/ 83EA02 //sub edx, 2
// L6:
/* 138 00000098*/ 89D6 //mov esi, edx
/* 139 0000009A*/ 83E6FC //and esi, -4
/* 140 0000009D*/ BB00000000 //mov ebx, 0
// L7:
/* 142 000000A2*/ 890C18 //mov DWORD [eax+ebx], ecx
/* 143 000000A5*/ 83C304 //add ebx, 4
/* 144 000000A8*/ 39F3 //cmp ebx, esi
/* 145 000000AA*/ 72F6 //jb L7
/* 146 000000AC*/ 01D8 //add eax, ebx
/* 147 000000AE*/ 89D3 //mov ebx, edx
/* 148 000000B0*/ 83E302 //and ebx, 2
/* 149 000000B3*/ 85DB //test ebx, ebx
/* 150 000000B5*/ 7406 //je L9
/* 151 000000B7*/ 668908 //mov WORD [eax], cx
/* 152 000000BA*/ 83C002 //add eax, 2
// L9:
/* 154 000000BD*/ 83E201 //and edx, 1
/* 155 000000C0*/ 85D2 //test edx, edx
/* 156 000000C2*/ 7405 //je L10
/* 157 000000C4*/ 8808 //mov BYTE [eax], cl
/* 158 000000C6*/ 83C001 //add eax, 1
// L10:
/* 160 000000C9*/ C744240408000000 //mov DWORD [esp+4], 8
/* 161 000000D1*/ 8D45D7 //lea eax, [ebp-41]
/* 162 000000D4*/ 890424 //mov DWORD [esp], eax
/* 163 000000D7*/ E82EFFFFFF //call _generateLicenseplate
/* 164 000000DC*/ 8845F7 //mov BYTE [ebp-9], al
/* 165 000000DF*/ B958000000 //mov ecx, _b
/* 166 000000E4*/ E839FFFFFF //call __ZN9testClass7getStrAEv
/* 167 000000E9*/ 89442404 //mov DWORD [esp+4], eax
/* 168 000000ED*/ C7042433000000 //mov DWORD esp, LC0
/* 169 000000F4*/ E80AFFFFFF //call _strcmp
/* 170 000000F9*/ 85C0 //test eax, eax
/* 171 000000FB*/ 0F94C0 //sete al
/* 172 000000FE*/ 84C0 //test al, al
/* 173 00000100*/ 7425 //je L11
/* 174 00000102*/ A116000000 //mov eax, DWORD _showTextBox
/* 175 00000107*/ C744240C00000000 //mov DWORD [esp+12], 0
/* 176 0000010F*/ C744240800000000 //mov DWORD [esp+8], 0
/* 177 00000117*/ C744240400000000 //mov DWORD [esp+4], 0
/* 178 0000011F*/ 8D55D7 //lea edx, [ebp-41]
/* 179 00000122*/ 891424 //mov DWORD [esp], edx
/* 180 00000125*/ FFD0 //call eax
// L11:
/* 182 00000127*/ B800000000 //mov eax, 0
/* 183 0000012C*/ 83C440 //add esp, 64
/* 184 0000012F*/ 5B //pop ebx
/* 186 00000130*/ 5E //pop esi
/* 188 00000131*/ 5D //pop ebp
/* 191 00000132*/ C3 //ret
// LFE2679:
// _internalCodeDeducePtr:
/* 196 00000133*/ 58 //popeax
/* 197 00000134*/ 50 //pusheax
/* 198 00000135*/ C3 //ret
// 204 ;.align 4
// _sdata:
/* 206 00000136*/ 00000000 //db00,00,00,00
/* 210 0000013A*/ E9C1FEFFFF //jmp_topCPPCodeLabel
// _memoryRet:
/* 212 0000013F*/ B878563412 //moveax, 0x12345678
/* 213 00000144*/ C3 //ret
// _callWrapper:
/* 216 00000145*/ E8E9FFFFFF //call_internalCodeDeducePtr
/* 217 0000014A*/ C3 //ret
// _replaceCodesWrapper:
// LFB2680:
/* 227 0000014B*/ 55 //push ebp
/* 230 0000014C*/ 89E5 //mov ebp, esp
/* 232 0000014E*/ 83EC18 //sub esp, 24
/* 233 00000151*/ 814508f5020000 //add DWORD [ebp+8], 16777215
/* 234 00000158*/ 8B4508 //mov eax, DWORD [ebp+8]
/* 235 0000015B*/ 8B550C //mov edx, DWORD [ebp+12]
/* 236 0000015E*/ 89542408 //mov DWORD [esp+8], edx
/* 237 00000162*/ C744240405000000 //mov DWORD [esp+4], 65535
/* 238 0000016A*/ 890424 //mov DWORD [esp], eax
/* 239 0000016D*/ E8B6000000 //call _replaceCodes
/* 240 00000172*/ C9 //leave
/* 243 00000173*/ C3 //ret
// LFE2680:
/* 248 00000174*/ 90 //nop
// _runCodeCtors:
/* 250 00000175*/ 60 //pushad
// LCODECTORSDATACALL:
/* 252 00000176*/ E81B010000 //call__GLOBAL__sub_I_gtarand
/* 253 0000017B*/ 90 //nop
/* 254 0000017C*/ 90 //nop
/* 255 0000017D*/ 90 //nop
/* 256 0000017E*/ 90 //nop
/* 257 0000017F*/ 61 //popad
/* 258 00000180*/ C3 //ret
ENDDUMP
_initCPPCode:
DUMP
// LFB2681:
/* 266 00000181*/ 55 //push ebp
/* 269 00000182*/ 89E5 //mov ebp, esp
/* 271 00000184*/ 83EC48 //sub esp, 72
/* 272 00000187*/ E8B3FFFFFF //call _memoryRet
/* 273 0000018C*/ 8945F4 //mov DWORD [ebp-12], eax
/* 274 0000018F*/ 817DF478563412 //cmp DWORD [ebp-12], 305419896
/* 275 00000196*/ 0F858A000000 //jne L14
/* 276 0000019C*/ C745F000000000 //mov DWORD [ebp-16], 0
/* 277 000001A3*/ E89DFFFFFF //call _callWrapper
/* 278 000001A8*/ 8945F0 //mov DWORD [ebp-16], eax
/* 279 000001AB*/ 836DF005 //sub DWORD [ebp-16], 5
/* 280 000001AF*/ 836DF001 //sub DWORD [ebp-16], 1
/* 281 000001B3*/ 836DF005 //sub DWORD [ebp-16], 5
/* 282 000001B7*/ 8B45F0 //mov eax, DWORD [ebp-16]
/* 283 000001BA*/ 8945EC //mov DWORD [ebp-20], eax
/* 284 000001BD*/ 8345EC01 //add DWORD [ebp-20], 1
/* 285 000001C1*/ 836DF005 //sub DWORD [ebp-16], 5
/* 286 000001C5*/ 8B45F0 //mov eax, DWORD [ebp-16]
/* 287 000001C8*/ 8945E8 //mov DWORD [ebp-24], eax
/* 288 000001CB*/ 8B45E8 //mov eax, DWORD [ebp-24]
/* 289 000001CE*/ 8945E4 //mov DWORD [ebp-28], eax
/* 290 000001D1*/ 8345E801 //add DWORD [ebp-24], 1
/* 291 000001D5*/ 8B45E8 //mov eax, DWORD [ebp-24]
/* 292 000001D8*/ 8B00 //mov eax, DWORD [eax]
/* 293 000001DA*/ 99 //cdq
/* 294 000001DB*/ 8945D8 //mov DWORD [ebp-40], eax
/* 295 000001DE*/ 8955DC //mov DWORD [ebp-36], edx
/* 296 000001E1*/ 8B45E4 //mov eax, DWORD [ebp-28]
/* 297 000001E4*/ 99 //cdq
/* 298 000001E5*/ 8945D0 //mov DWORD [ebp-48], eax
/* 299 000001E8*/ 8955D4 //mov DWORD [ebp-44], edx
/* 300 000001EB*/ 8345D005 //add DWORD [ebp-48], 5
/* 301 000001EF*/ 8355D400 //adc DWORD [ebp-44], 0
/* 302 000001F3*/ 8B45D0 //mov eax, DWORD [ebp-48]
/* 303 000001F6*/ 8B55D4 //mov edx, DWORD [ebp-44]
/* 304 000001F9*/ 0145D8 //add DWORD [ebp-40], eax
/* 305 000001FC*/ 1155DC //adc DWORD [ebp-36], edx
/* 306 000001FF*/ 8B55D8 //mov edx, DWORD [ebp-40]
/* 307 00000202*/ 8B45D8 //mov eax, DWORD [ebp-40]
/* 308 00000205*/ 89542404 //mov DWORD [esp+4], edx
/* 309 00000209*/ 890424 //mov DWORD [esp], eax
/* 310 0000020C*/ E83AFFFFFF //call _replaceCodesWrapper
/* 311 00000211*/ 8B45EC //mov eax, DWORD [ebp-20]
/* 312 00000214*/ 8B55D8 //mov edx, DWORD [ebp-40]
/* 313 00000217*/ 8910 //mov DWORD [eax], edx
/* 314 00000219*/ E821FFFFFF //call _memoryRet
/* 315 0000021E*/ 8945F4 //mov DWORD [ebp-12], eax
/* 316 00000221*/ E84FFFFFFF //call _runCodeCtors
// L14:
/* 318 00000226*/ C9 //leave
/* 321 00000227*/ C3 //ret
// LFE2681:
// _replaceCodes:
// LFB2682:
/* 329 00000228*/ 55 //push ebp
/* 332 00000229*/ 89E5 //mov ebp, esp
/* 334 0000022B*/ 83EC10 //sub esp, 16
/* 335 0000022E*/ C745FC00000000 //mov DWORD [ebp-4], 0
/* 336 00000235*/ EB37 //jmp L17
// L18:
/* 338 00000237*/ 8B45FC //mov eax, DWORD [ebp-4]
/* 339 0000023A*/ 8D148500000000 //lea edx, [0+eax*4]
/* 340 00000241*/ 8B4508 //mov eax, DWORD [ebp+8]
/* 341 00000244*/ 01D0 //add eax, edx
/* 342 00000246*/ 8B00 //mov eax, DWORD [eax]
/* 343 00000248*/ 8945F8 //mov DWORD [ebp-8], eax
/* 344 0000024B*/ 8B4510 //mov eax, DWORD [ebp+16]
/* 345 0000024E*/ 0145F8 //add DWORD [ebp-8], eax
/* 346 00000251*/ 8B45F8 //mov eax, DWORD [ebp-8]
/* 347 00000254*/ 8945F4 //mov DWORD [ebp-12], eax
/* 348 00000257*/ 8B45F4 //mov eax, DWORD [ebp-12]
/* 349 0000025A*/ 8B00 //mov eax, DWORD [eax]
/* 350 0000025C*/ 89C2 //mov edx, eax
/* 351 0000025E*/ 8B4510 //mov eax, DWORD [ebp+16]
/* 352 00000261*/ 01D0 //add eax, edx
/* 353 00000263*/ 89C2 //mov edx, eax
/* 354 00000265*/ 8B45F4 //mov eax, DWORD [ebp-12]
/* 355 00000268*/ 8910 //mov DWORD [eax], edx
/* 356 0000026A*/ 8345FC01 //add DWORD [ebp-4], 1
// L17:
/* 358 0000026E*/ 8B45FC //mov eax, DWORD [ebp-4]
/* 359 00000271*/ 3B450C //cmp eax, DWORD [ebp+12]
/* 360 00000274*/ 7CC1 //jl L18
/* 361 00000276*/ C9 //leave
/* 364 00000277*/ C3 //ret
// LFE2682:
// replaceCodesSpacePlaceCreate:
// __Z41__static_initialization_and_destruction_0ii:
// LFB2742:
/* 377 00000278*/ 55 //push ebp
/* 380 00000279*/ 89E5 //mov ebp, esp
/* 382 0000027B*/ 837D0801 //cmp DWORD [ebp+8], 1
/* 383 0000027F*/ 7513 //jne L19
/* 384 00000281*/ 817D0CFFFF0000 //cmp DWORD [ebp+12], 65535
/* 385 00000288*/ 750A //jne L19
/* 386 0000028A*/ B958000000 //mov ecx, _b
/* 387 0000028F*/ E8A6FDFFFF //call __ZN9testClassC1Ev
// L19:
/* 389 00000294*/ 5D //pop ebp
/* 392 00000295*/ C3 //ret
// LFE2742:
// __GLOBAL__sub_I_gtarand:
// LFB2743:
/* 399 00000296*/ 55 //push ebp
/* 402 00000297*/ 89E5 //mov ebp, esp
/* 404 00000299*/ 83EC08 //sub esp, 8
/* 405 0000029C*/ C7442404FFFF0000 //mov DWORD [esp+4], 65535
/* 406 000002A4*/ C7042401000000 //mov DWORD [esp], 1
/* 407 000002AB*/ E8C8FFFFFF //call __Z41__static_initialization_and_destruction_0ii
/* 408 000002B0*/ C9 //leave
/* 411 000002B1*/ C3 //ret
// LFE2743:
// 415 ;.align 4
// 416 ;.long __GLOBAL__sub_I_gtarand
// "GCC:
/* 424 000002B2*/ 202D6578706F72743A //db' -export:\replaceCodes\', 00
/* 424 000002BB*/ 5C7265706C61636543
/* 424 000002C4*/ 6F6465735C00
/* 425 000002CA*/ 202D6578706F72743A //db' -export:\initCPPCode\', 00
/* 425 000002D3*/ 5C696E697443505043
/* 425 000002DC*/ 6F64655C00
/* 426 000002E1*/ 202D6578706F72743A //db' -export:\codeMain\', 00
/* 426 000002EA*/ 5C636F64654D61696E
/* 426 000002F3*/ 5C00
//replaceCodesSpacePlace:
49000000 e0000000 f0000000 03010000 8b020000
ENDDUMP
Versão 2.0:
SpoilerAbrir
Esta versão funciona de um modo bem diferente da versão anterior, trabalhando com arquivo de formato COFF que é o que geralmente compiladores usam como output para compilação com vários sources, portanto não necessitando de um programa assembler separado.
As diferenças mais notáveis entre a versão nova e a antiga é que na nova um assembler separado e também as headers especiais para os construtores e variáveis estáticas funcionarem não são mais necessários.
Programa em desenvolvimento ainda, pode conter bugs, menu não terminado, use por sua própria conta e risco.
Testado com o MinGW.
Exemplo:
As diferenças mais notáveis entre a versão nova e a antiga é que na nova um assembler separado e também as headers especiais para os construtores e variáveis estáticas funcionarem não são mais necessários.
Programa em desenvolvimento ainda, pode conter bugs, menu não terminado, use por sua própria conta e risco.
Testado com o MinGW.
Exemplo:
Código: Selecionar tudo
/****************************************************************************
* http://bms.mixmods.com.br/t4721-
*
*
*/
//#include "includes/top.h" // NÃO MAIS NECESSÁRIO
#include <cstring> // Protótipos das funções de string de C, como por exemplo strcmp, entre outras.
#include <cstdint>
struct CVehicle;
extern "C" char __cdecl showTextBox(const char *a1, char a2, char a3, char a4);
class testClass
{
int a;
const char *strA;
public:
const char *getStrA() const
{
return strA;
}
// Suporte a construtores
testClass() : strA("ABCDEF")
{
a = 10;
}
};
testClass potassio;
struct externalCallbackStructure
{
CVehicle *veh;
int32_t status;
};
void callback(const externalCallbackStructure *test)
{
}
extern "C" int __declspec(dllexport) codeMain(int i)
{
//testClass asdawdaw;
asm("nop\n");
showTextBox(potassio.getStrA(), 0, 0, 0);
asm("nop\n");
return 0;
}
///************************************ FINAL DO ARQUIVO CPP ********************************************************
//#include "includes/btn.h" // NÃO MAIS NECESSÁRIO
Código: Selecionar tudo
SCRIPT_START
{
LVAR_INT init main rtn
GET_LABEL_POINTER _initCPPCode init
GET_LABEL_POINTER _codeMain main
CALL_FUNCTION init 0 0
ad_infinitum:
WAIT 5000
CALL_FUNCTION_RETURN main 1 1 (0) (rtn)
GOTO ad_infinitum
}
SCRIPT_END
getCodeTopAddress:
DUMP
e8 01 00 00 00 c3 8b 04 24 83 e8 05 c3
ENDDUMP
__Z8callbackPK25externalCallbackStructure:
DUMP
55 89 e5 5d c3
ENDDUMP
_codeMain:
DUMP
55 89 e5 83 ec 18 90 b9 00 00 00 00 e8 6a 00 00 00 c7 44 24 0c 00 00 00 00 c7 44 24 08 00 00 00 00 c7 44 24 04 00 00 00 00
89 04 24 e8 ba 01 00 00 90 b8 00 00 00 00 c9 c3
ENDDUMP
__Z41__static_initialization_and_destruction_0ii:
DUMP
55 89 e5 83 7d 08 01 75 13 81 7d 0c ff ff 00 00 75 0a b9 00 00 00 00 e8 42 00 00 00 5d c3
ENDDUMP
__GLOBAL__sub_I_potassio:
DUMP
55 89 e5 83 ec 08 c7 44 24 04 ff ff 00 00 c7 04 24 01 00 00 00 e8 c8 ff ff ff c9 c3
ENDDUMP
.bss:
DUMP
00 00 00 00 00 00 00 00
ENDDUMP
.text$_ZNK9testClass7getStrAEv:
DUMP
55 89 e5 83 ec 04 89 4d fc 8b 45 fc 8b 40 04 c9 c3 90 90 90
ENDDUMP
.rdata:
DUMP
41 42 43 44 45 46 00 00
ENDDUMP
.text$_ZN9testClassC1Ev:
DUMP
55 89 e5 83 ec 04 89 4d fc 8b 45 fc c7 40 04 00 00 00 00 8b 45 fc c7 00 0a 00 00 00 c9 c3 90 90
ENDDUMP
.ctors:
DUMP
5c 00 00 00
ENDDUMP
.rdata$zzz:
DUMP
47 43 43 3a 20 28 47 4e 55 29 20 34 2e 38 2e 31 00 00 00 00
ENDDUMP
.drectve:
DUMP
20 2d 65 78 70 6f 72 74 3a 22 63 6f 64 65 4d 61 69 6e 22 00
ENDDUMP
.eh_frame$_ZNK9testClass7getStrAEv:
DUMP
14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00 74 ff ff ff 11 00 00 00 00
41 0e 08 85 02 42 0d 05 4d c5 0c 04 04 00 00
ENDDUMP
.eh_frame$_ZN9testClassC1Ev:
DUMP
14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00 58 ff ff ff 1e 00 00 00 00
41 0e 08 85 02 42 0d 05 5a c5 0c 04 04 00 00
ENDDUMP
.eh_frame:
DUMP
14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00 84 fe ff ff 05 00 00 00 00
41 0e 08 85 02 42 0d 05 41 c5 0c 04 04 00 00 1c 00 00 00 3c 00 00 00 64 fe ff ff 39 00 00 00 00 41 0e 08 85 02 42 0d 05
75 c5 0c 04 04 00 00 1c 00 00 00 5c 00 00 00 44 fe ff ff 1e 00 00 00 00 41 0e 08 85 02 42 0d 05 5a c5 0c 04 04 00 00 1c
00 00 00 7c 00 00 00 24 fe ff ff 1c 00 00 00 00 41 0e 08 85 02 42 0d 05 58 c5 0c 04 04 00 00
ENDDUMP
_showTextBox:
DUMP
68 e0 8b 58 00 c3
ENDDUMP
reallocationFunction:
DUMP
55 89 e5 83 ec 20 8b 45 08 89 45 f8 81 45 f8 71 02 00 00 8b 45 f8 89 45 f4 c7 45 f0 04 00 00 00 c7 45 fc 00 00 00 00 eb 3b
8b 55 fc 89 d0 01 c0 01 d0 c1 e0 02 89 c2 8b 45 f4 01 d0 89 45 ec 8b 45 ec 8b 00 89 c2 8b 45 08 01 d0 89 45 e8 8b 45 ec
8b 40 04 89 c2 8b 45 08 01 c2 8b 45 e8 89 10 83 45 fc 01 8b 45 fc 3b 45 f0 7c bd c9 c3
ENDDUMP
relocationTable:
DUMP
1a 00 00 00 85 00 00 00 06 00 00 00 5e 00 00 00 85 00 00 00 06 00 00 00 b8 00 00 00 a1 00 00 00 06 00 00 00 c9 00 00 00 69
00 00 00 06 00 00 00 90 90 90 90 90 90 90 90
ENDDUMP
_initCPPCode:
DUMP
60 9c 90 e8 4f fd ff ff 90 50 e8 4b ff ff ff 83 c4 04 e8 a9 fd ff ff 9d 61 c3
ENDDUMP
Download 1.0 (source incluído): https://drive.google.com/file/d/0B2ebUk ... sp=sharing
Downloads da versão 2.0:
Source: https://github.com/Fabio3rs/COFF-to-GTAScript-Helper
Compilado: https://drive.google.com/file/d/13ddGbT ... sp=sharing
Tópico antigo http://brmodstudio.forumeiros.com/t4721-
Exemplo de possibilidade do programa:
Transformar um código C++ de geração de função callback que ao ser chamada nativamente chama um script para assembly e inserir dentro do próprio script, para quem está familiar com o Moonloader lembra um pouco o funcionamento da ffi.
Código: Selecionar tudo
{$CLEO .cs}
0AC6: 0@ = label @_initCPPCode offset
0AA5: call_function 0@ num_params 0 pop 0
//0AA2: 0@ = load_library "cppToCleo.asi" // IF and SET
//0AA4: 1@ = get_proc_address "generateFunction" library 0@ // IF and SET
//0A9F: 4@ = current_thread_pointer
//0AA7: call_function 1@ num_params 4 pop 4 0 0 @noCheats 4@ -> 3@ // cleoToCppCallBackLabel
0AB1: call_scm_func @generateFunctionCallback 3 @noCheats 0 0 -> 3@
2@ = 0x008A5B58
while 2@ < 0x008A5CC8
0A8C: write_memory 2@ size 4 value 3@ virtual_protect 1
2@ += 4
end
while true
wait 0x7FFFFFFF
end
:noCheats
0AD1: show_formatted_text_highpriority "Cheats nao sao permitidos" time 5000
wait 0
:generateFunctionCallback // {label, nparams, popbytes} -> Returns function address
0AC6: 30@ = label @_getCallBackSize offset
0AA7: call_function 30@ num_params 0 pop 0 -> 31@
0AC8: 29@ = allocate_memory_size 31@
0AC6: 10@ = label @_generateFunction offset
0A9F: 4@ = current_thread_pointer
0AA7: call_function 10@ num_params 5 pop 5 2@ 1@ 0@ 4@ 29@ -> 11@ // cleoToCppCallBackLabel
0AB2: ret 1 11@
HEX
e8 01 00 00 00 c3 8b 04 24 83 e8 05 c3 55 31 c0 89 e5 8b 4d 08 53 8b 5d 0c 3b 45 10 74 09 8a 14 03 88 14 01 40 eb f2 5b 5d c3 55 89 e5 57 56 53 81 ec 0c 01 00 00 8b 5d 0c 8b 55 08 85
db 0f 84 33 01 00 00 8b 83 e8 00 00 00 83 78 10 00 0f 84 23 01 00 00 8d b5 0c ff ff ff 31 c0 b9 02 00 00 00 89 f7 f3 ab 8d 85 1c ff ff ff c7 85 04 ff ff ff 00 00 00 00 8d 4d 9c c7
85 08 ff ff ff 00 00 00 00 c7 85 14 ff ff ff 00 00 00 00 c7 85 18 ff ff ff 00 00 00 00 66 c7 85 3c ff ff ff 00 00 c6 45 c8 00 c6 45 c9 00 c6 45 ca 00 c6 45 cb 00 c6 45 cc 00 c6 45
cd ff c7 45 d0 00 00 00 00 66 c7 45 d4 00 00 c6 45 d6 00 c6 45 d7 01 c6 45 d8 00 c7 45 dc 00 00 00 00 c6 45 e0 00 66 c7 45 e2 ff ff c6 45 e4 00 c7 00 00 00 00 00 83 c0 04 39 c8 75
f3 8d 85 40 ff ff ff 8d 4d c0 c7 00 00 00 00 00 83 c0 04 39 c8 75 f3 c7 45 c4 00 00 00 00 8d 7b 04 b9 e1 00 00 00 c7 45 c0 00 00 00 00 8d b5 04 ff ff ff f3 a4 8b 83 e8 00 00 00 8b
40 10 c6 83 cb 00 00 00 01 c6 83 c8 00 00 00 01 89 53 40 89 43 14 8b 83 ec 00 00 00 89 43 18 8b 83 f0 00 00 00 c1 e0 02 89 44 24 08 8b 42 10 89 44 24 04 8d 43 44 83 c3 04 89 04 24
e8 9f fe ff ff 89 1c 24 ff 15 09 03 00 00 81 c4 0c 01 00 00 5b 5e 5f 5d c3
END
:_getCallBackSize // (void) -> Returns struct size
HEX
55 b8 20 01 00 00 89 e5 5d c3
END
:_generateFunction // (cppToCleoCallback *nCallback, CRunningScript *owner, int atLabel, int nparams, int popBytes) -> Returns function address
HEX
55 89 e5 57 56 53 83 ec 4c 8b 5d 08 8b 45 10 8b 4d 14 8b 55 0c 8d bb f4 00 00 00 89 7d c4 8d bb 0b 01 00 00 89 8b f0 00 00 00 89 c1 c1 f9 1f 31 c8 29 c8 03 42 10 89 1b 89 93 e8 00 00
00 89 83 ec 00 00 00 c6 83 f4 00 00 00 60 c6 83 f5 00 00 00 80 c7 83 f6 00 00 00 44 24 0c 04 c6 83 fa 00 00 00 9c c6 83 fb 00 00 00 54 c6 83 fc 00 00 00 68 89 9b fd 00 00 00 c6 83
01 01 00 00 68 c7 83 02 01 00 00 2a 00 00 00 c6 83 06 01 00 00 68 c7 83 07 01 00 00 00 00 00 00 c6 83 0b 01 00 00 e8 c7 83 0c 01 00 00 00 00 00 00 66 c7 83 10 01 00 00 83 c4 c6 83
12 01 00 00 10 c6 83 13 01 00 00 80 c7 83 14 01 00 00 6c 24 10 04 c6 83 18 01 00 00 9d c6 83 19 01 00 00 61 8b 45 18 80 3d 11 05 00 00 00 c6 83 1a 01 00 00 c2 66 89 83 1b 01 00 00
75 07 c6 05 11 05 00 00 01 8d 75 d8 8d 45 d0 89 74 24 04 89 04 24 c7 44 24 08 00 00 00 00 89 7d d8 e8 7e 01 00 00 8d 45 d4 89 f1 89 04 24 c7 44 24 04 00 00 00 00 89 45 c0 89 7d d4
e8 9b 00 00 00 89 f1 50 50 c6 83 0b 01 00 00 e8 bb 08 03 00 00 e8 da 00 00 00 8b 45 c0 8d 57 01 89 f1 29 fb c7 44 24 04 00 00 00 00 89 55 d4 89 04 24 e8 69 00 00 00 89 f1 50 50 89
5f 01 e8 b1 00 00 00 8b 45 c4 8d 65 f4 5b 5e 5f 5d c3 90 90 25 03 00 00 55 89 e5 8b 55 10 8b 45 0c 89 55 0c 8b 55 14 89 55 08 5d ff e0 90 90 90 83 3d 0d 05 00 00 00 55 89 e5 8b 4d
08 75 1a 80 3d 11 05 00 00 00 75 07 c6 05 11 05 00 00 01 c7 05 0d 05 00 00 00 9f 46 00 a1 0d 05 00 00 5d ff e0 90 90 90 55 89 e5 53 89 cb 83 ec 14 8b 45 0c c7 01 00 00 00 00 85 c0
75 06 c6 41 0c 00 eb 30 8b 55 08 8d 49 08 89 41 fc 8b 12 89 51 f8 89 4c 24 0c c7 44 24 08 40 00 00 00 89 44 24 04 89 14 24 ff 15 51 07 00 00 83 ec 10 85 c0 0f 95 43 0c 8b 5d fc c9
c2 08 00 90 80 79 0c 00 74 33 55 89 e5 53 83 ec 24 8b 51 04 8b 41 08 89 d3 8b 11 8d 4d f4 89 45 f4 89 5c 24 04 89 4c 24 0c 89 44 24 08 89 14 24 ff 15 51 07 00 00 8b 5d fc 83 ec 10
c9 c3 90 90 55 89 e5 53 83 ec 34 8b 45 08 8d 4d e8 8b 18 0f b6 45 0c 89 5d e4 89 44 24 04 8d 45 e4 89 04 24 e8 4b ff ff ff 8d 4d e8 50 50 8a 1b e8 93 ff ff ff 88 d8 8b 5d fc c9 c3
55 89 e5 57 56 53 83 ec 3c 8b 45 10 8b 5d 0c 8d 75 d8 8b 7d 08 0f b6 c8 89 45 c4 8b 03 89 4c 24 04 89 34 24 89 4d c0 89 45 d8 e8 99 ff ff ff 3c e8 0f 82 a3 00 00 00 3c e9 76 0c fe
c0 8b 4d c0 74 42 e9 93 00 00 00 8b 1b 80 7d c4 01 8d 43 05 89 45 c0 19 c0 f7 d0 83 e0 04 8d 4b 01 89 44 24 04 8d 45 d4 89 4d d4 89 f1 89 04 24 e8 c7 fe ff ff 51 51 89 f1 8b 5b 01
e8 0f ff ff ff 03 5d c0 89 1f eb 5c 8b 03 89 4c 24 04 89 34 24 40 89 45 d8 e8 32 ff ff ff 3c 15 74 04 3c 25 75 3c 80 7d c4 01 8b 13 19 c0 f7 d0 83 e0 04 8d 4a 02 89 44 24 04 8d 45
d4 89 04 24 89 4d d4 89 f1 89 55 c0 e8 73 fe ff ff 89 f1 52 52 8b 55 c0 8b 5a 02 e8 b8 fe ff ff 8b 03 89 07 eb 06 c7 07 00 00 00 00 8d 65 f4 89 f8 5b 5e 5f 5d c3 90 90 00 00 00 00
00 00 00 00 00 00 00 00 47 43 43 3a 20 28 47 4e 55 29 20 34 2e 38 2e 31 00 00 00 00 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00
bc fd ff ff 15 00 00 00 00 41 0e 08 85 02 42 0d 05 50 c5 0c 04 04 00 00 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 1c 00 00 00 1c 00 00 00 9c fd ff ff
31 00 00 00 00 48 0e 08 85 02 42 0d 05 65 c5 0c 04 04 00 00 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 20 00 00 00 1c 00 00 00 98 fd ff ff 53 00 00 00
00 41 0e 08 85 02 42 0d 05 41 83 03 02 4c c5 c3 0c 04 04 00 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 20 00 00 00 1c 00 00 00 b0 fd ff ff 3a 00 00 00
00 47 0e 08 85 02 42 0d 05 44 83 03 6c c5 c3 0c 04 04 00 00 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 20 00 00 00 1c 00 00 00 d4 f9 ff ff 1d 00 00 00
00 41 0e 08 85 02 44 0d 05 44 83 03 52 c3 41 c5 0c 04 04 00 2c 00 00 00 40 00 00 00 b0 f9 ff ff 58 01 00 00 00 41 0e 08 85 02 42 0d 05 49 87 03 86 04 83 05 03 48 01 c3 41 c6 41 c7
41 c5 0c 04 04 00 00 00 1c 00 00 00 70 00 00 00 80 f9 ff ff 0a 00 00 00 00 41 0e 08 85 02 47 0d 05 41 c5 0c 04 04 00 00 2c 00 00 00 90 00 00 00 60 f9 ff ff 7b 01 00 00 00 41 0e 08
85 02 42 0d 05 46 87 03 86 04 83 05 03 6e 01 c3 41 c6 41 c7 41 c5 0c 04 04 00 00 00 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 20 00 00 00 1c 00 00 00
f4 fc ff ff 38 00 00 00 00 41 0e 08 85 02 42 0d 05 44 83 03 70 c5 c3 0c 04 04 00 00 14 00 00 00 00 00 00 00 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 28 00 00 00 1c 00 00 00
f0 fc ff ff ea 00 00 00 00 41 0e 08 85 02 42 0d 05 46 87 03 86 04 83 05 02 dd c3 41 c6 41 c7 41 c5 0c 04 04 2c 80 85 00 55 89 e5 83 ec 20 8b 45 08 89 45 f8 81 45 f8 bf 07 00 00 8b
45 f8 89 45 f4 c7 45 f0 0d 00 00 00 c7 45 fc 00 00 00 00 eb 37 8b 45 fc 8d 14 c5 00 00 00 00 8b 45 f4 01 d0 89 45 ec 8b 45 ec 8b 00 89 c2 8b 45 08 01 d0 89 45 e8 8b 45 ec 8b 40 04
89 c2 8b 45 08 01 c2 8b 45 e8 89 10 83 45 fc 01 8b 45 fc 3b 45 f0 7c c1 c9 c3 73 01 00 00 09 03 00 00 10 02 00 00 2a 00 00 00 6a 02 00 00 11 05 00 00 81 02 00 00 11 05 00 00 ca 02
00 00 08 03 00 00 09 03 00 00 25 03 00 00 27 03 00 00 0d 05 00 00 36 03 00 00 11 05 00 00 3f 03 00 00 11 05 00 00 46 03 00 00 0d 05 00 00 4f 03 00 00 0d 05 00 00 98 03 00 00 51 07
00 00 db 03 00 00 51 07 00 00 90 90 90 90 90 90 90 90
END
:_initCPPCode
HEX
60 9c e8 ca f7 ff ff 50 e8 19 ff ff ff 83 c4 04 9d 61 c3
END
Código: Selecionar tudo
/****************************************************************************
* http://bms.mixmods.com.br/t4721-
*
*
*/
#include <cstring> // Protótipos das funções de string de C, como por exemplo strcmp, entre outras.
#include <cstdint>
#include "dynamic_hooker.hpp"
#include "script.h"
extern "C" void *memcpy(void *destination, const void *source, size_t num)
{
const uint8_t *src = (const uint8_t*)source;
uint8_t *dest = (uint8_t*)destination;
for (size_t i = 0; i < num; i++)
{
dest[i] = src[i];
}
}
auto CRunningScript__Process = injector::thiscall<char(CRunningScript *)>::call<0x00469F00>;
struct cppToCleoCallback
{
uintptr_t address;
CRunningScript fakeScript;
CRunningScript *owner;
uint8_t *startIp;
int nparams;
injectcode::dynamic_hooker::newCode myCode;
void run(injector::reg_pack &c)
{
if (owner->baseIP == nullptr)
return;
fakeScript = CRunningScript();
fakeScript.baseIP = owner->baseIP;
fakeScript.curIP = startIp;
fakeScript.IsExternalThread = true;
fakeScript.isActive = true;
fakeScript.tls[0].pParam = std::addressof(c);
memcpy(&(fakeScript.tls[1]), (void*)(c.esp), nparams * 4);
CRunningScript__Process(&fakeScript);
}
};
extern "C" __declspec(dllexport) int getCallBackSize()
{
return sizeof(cppToCleoCallback);
}
extern "C" void runCleoCallback(injector::reg_pack &c, uintptr_t address)
{
cppToCleoCallback *cb = (cppToCleoCallback*)address;
if (cb)
{
cb->run(c);
}
}
extern "C" __declspec(dllexport) injectcode::dynamic_hooker::newCode* generateFunction(cppToCleoCallback *nCallback, CRunningScript *owner, int atLabel, int nparams, int popBytes)
{
if (atLabel < 0)
{
atLabel = -atLabel;
}
nCallback->address = (uintptr_t)nCallback;
//nCallback->baseIp = owner->baseIP;
nCallback->owner = owner;
nCallback->nparams = nparams;
nCallback->startIp = std::addressof(owner->baseIP[atLabel]);
memset(std::addressof(nCallback->myCode), 0, sizeof(nCallback->myCode));
injectcode::dynamic_hooker::genDynamicCall(nCallback->myCode, nCallback->address, runCleoCallback, popBytes);
return std::addressof(nCallback->myCode);
}Código: Selecionar tudo
#pragma once
#ifndef _LUA_HOOKER_DYNAMIC_HOOKER_H_
#define _LUA_HOOKER_DYNAMIC_HOOKER_H_
#include <cstdint>
#include <injector\calling.hpp>
#include <algorithm>
#include <string>
#include <vector>
#define PACKED __attribute__ ((packed))
namespace injector
{
#pragma pack(push, 1)
struct reg_pack
{
// The ordering is very important, don't change
// The first field is the last to be pushed and first to be poped
// PUSHFD / POPFD
uint32_t ef;
// PUSHAD/POPAD -- must be the lastest fields (because of esp)
union
{
uint32_t arr[8];
struct { uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; };
};
void *retn;
enum reg_name {
reg_edi, reg_esi, reg_ebp, reg_esp, reg_ebx, reg_edx, reg_ecx, reg_eax
};
enum ef_flag {
carry_flag = 0, parity_flag = 2, adjust_flag = 4, zero_flag = 6, sign_flag = 7,
direction_flag = 10, overflow_flag = 11
};
uint32_t& operator[](size_t i)
{ return this->arr[i]; }
const uint32_t& operator[](size_t i) const
{ return this->arr[i]; }
template<uint32_t bit> // bit starts from 0, use ef_flag enum
bool flag()
{
return (this->ef & (1 << bit)) != 0;
}
bool jnb()
{
return flag<carry_flag>() == false;
}
} PACKED;
#pragma pack(pop)
}
namespace injectcode{
typedef void(__cdecl *callback_t)(injector::reg_pack&, uintptr_t address);
inline void callwrapper(uintptr_t retAddr, callback_t cb, uintptr_t address, injector::reg_pack *r)
{
cb(*r, address);
}
class dynamic_hooker{
public:
#pragma pack(push, 1)
struct newCode
{
uint8_t pushad; // pushad
// add[esp + 12], 4
uint8_t add;
uint32_t data;
uint8_t pushfd; // pushfd
uint8_t pushesp; // push esp
uint8_t push;
uintptr_t pushaddr;
uint8_t push2;
uintptr_t useraddr;
uint8_t push3;
uintptr_t retaddr;
// call callwrapper
uint8_t call;
uint32_t addr;
// add esp, 16
uint16_t addesp;
uint8_t addespnum;
// sub[esp + 12 + 4], 4
uint8_t sub;
uint32_t data1;
uint8_t popfd; // popfd
uint8_t popad; // popad
// retn x
uint8_t retn;
uint16_t retnsiz;
} PACKED;
#pragma pack(pop)
public:
static void genDynamicCall(newCode &myCode, uintptr_t address, callback_t c, uintptr_t popBytes)
{
myCode = newCode{
0x60, // pushad
0x80, 0x040C2444u, // add[esp + 12], 4
0x9C, // pushfd
0x54, // push esp
0x68, address, // push address
0x68, uintptr_t(c), // push c
0x68, 0x00, // push <retnaddr>
0xE8, 0x00, // call callwrapper
0xC483, 0x10, // add esp, 16
0x80, 0x0410246Cu, // sub[esp + 12 + 4], 4
0x9D, // popfd
0x61, // popad
0xC2, 0x00 // retn x
};
myCode.retnsiz = popBytes;
injector::MakeCALL(&(myCode.call), callwrapper, false);
}
inline dynamic_hooker()
{
}
inline ~dynamic_hooker()
{
}
} PACKED;
}
#endif
Disclaimer: não garanto o funcionamento do programa, use por sua própria conta e risco.