📄 compiler.cpp
字号:
/*++
Copyright (c) 2005 Godness
Contact information:
mail: godness@omen.ru
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Module Name:
compiler.cpp
Abstract: This module exported one function - Compile(), that compile given
condition to executable code for the eXTreme tRaCer Engine
Revision History:
Godness 01/10/2005
Initial release
--*/
extern "C" {
#pragma warning ( push, 3 )
#include <ntddk.h>
#pragma warning ( pop )
}
#pragma warning ( disable: 4309 ) // "truncation of constant value"
struct str_compiled_condition
{
str_compiled_condition *next;
str_compiled_condition *prev;
char flags; // 0x1 - jump opcode was invert; 0x2 - use long jump;
char brackets_right;
char brackets_left;
char short_opcode_jump;
char short_address_jump;
short long_opcode_jump;
int long_address_jump;
short size_compiled_code;
char mas_compiled_code[1];
};
typedef str_compiled_condition *pcompiled_condition;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
char stub_code[7] = {0x55, 0x89, 0xE5, 0x31, 0xC0, 0xC9, 0xC3};
// ^^^^^^^^^
// push ebp
// mov ebp, esp
// xor eax, eax
// leave
// ret
char compiled_code[0x800] = {0x55, 0x89, 0xE5, 0x31, 0xC0, 0xC9, 0xC3};
char mas_temp_struct[0x800];
char mas_for_cmps[0x100];
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
char *mas_type_conv[] =
{
"byte", "word", "dword"
};
char *mas_registers[] =
{
"edi", "esi", "ebp", "esp", "ebx", "edx", "ecx", "eax", "eip", "cs", "eflags",
"di", "si", "bp", "sp", "bx", "dx", "cx", "ax",
"bl", "dl", "cl", "al",
"bh", "dh", "ch", "ah"
};
char mas_reg_offset[] =
{
0x08, 0x0C, 0x10, 0x34, 0x18, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30,
0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x20, 0x24,
0x18, 0x1C, 0x20, 0x24,
0x19, 0x1D, 0x21, 0x25
};
char *mas_conditions_equal[] =
{
"==", "!=", ">=", "<=", ">", "<"
};
char byte_for_reverse_eflags = 0;
char mas_conditions_opcode[] =
{
0x74, 0x75, 0x73, 0x76, 0x77, 0x72
};
char *mas_logic_conditions[] =
{
"&&", "||"
};
char mas_exit_command[] =
{
0x31, 0xC0, 0xEB, 0x02, 0xB0, 0x01, 0xC9, 0xC3
//^^^^^^^^^^^^^^^^
// xor eax, eax
// jmp exit
// mov al, 0x01
//exit:
// leave
// ret
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void CorrectJumpLength(pcompiled_condition pelem);
bool CompileConditionInBrackets(char *buffer, pcompiled_condition pmas);
bool CompileOneCondition(char *&buffer, pcompiled_condition mas);
char FindLogicCondition(char *&buffer);
bool FindEqualCondition(char *&buffer, char &condition_opcode);
bool FindRegister(char *&buffer, char ®_offset, char ®_size);
bool my_atoi(char *&buffer, ULONG& value);
bool FindPointerCondition(char *&buffer, int &pointer_level, int &type_convertion);
bool FindBinaryCondition(char *&buffer, int &out_type, int &out_size, char *out_massive);
bool si_atoi(PCSTR string, ULONG& value);
extern void* CheckAddressAndMakePageIn(void *address);
int OffsetOfMakePageInFunction = (int)(&CheckAddressAndMakePageIn);
////////////////////////////////////////////////////////////////////////////
//
// Compile() - function that compile given condition to execute code
//
////////////////////////////////////////////////////////////////////////////
bool Compile(char *buffer)
{
pcompiled_condition pmas_pointer = (pcompiled_condition)mas_temp_struct;
char *mas = (char *)compiled_code;
memset(mas, 0, sizeof(compiled_code));
memcpy(mas, stub_code, sizeof(stub_code));
mas += 3;
if (!CompileConditionInBrackets(buffer, pmas_pointer))
return false;
CorrectJumpLength(pmas_pointer);
do
{
memcpy(mas, pmas_pointer->mas_compiled_code, pmas_pointer->size_compiled_code);
mas += pmas_pointer->size_compiled_code;
if (pmas_pointer->flags & 0x2)
{
memcpy(mas, &pmas_pointer->long_opcode_jump, 6);
mas += 6;
}
else
{
memcpy(mas, &pmas_pointer->short_opcode_jump, 2);
mas += 2;
}
}
while ((pmas_pointer = pmas_pointer->next) != 0);
memcpy(mas, (char *)&mas_exit_command, sizeof(mas_exit_command));
return true;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void CorrectJumpLength(pcompiled_condition pelem)
{
pcompiled_condition ptemp = NULL;
ULONG size = 0;
char level = 0;
while (pelem->next)
pelem = pelem->next;
do
{
ptemp = pelem;
level = 0;
size = 0;
while ((ptemp = ptemp->next) != 0)
{
size += ptemp->size_compiled_code + ((ptemp->flags & 0x2) ? 6 : 2);
if (ptemp->next)
{
if (ptemp->brackets_left)
level = level + ptemp->brackets_left;
if (level && ptemp->brackets_right)
{
int i = ptemp->brackets_right;
while (level && i)
{
--level;
--i;
}
}
}
else
level = 0;
if (pelem->flags & 0x1)
{
if ((!ptemp->next) || (!level && !(ptemp->flags & 0x1)))
break;
}
else
{
if (!ptemp->next)
{
size += 4;
break;
}
if (!level && (ptemp->flags & 0x1) && ptemp->brackets_right)
break;
}
}
if (size == 0) size = 4;
if (size > 0x7F)
{
pelem->flags |= 0x2;
pelem->long_opcode_jump = ( ((pelem->short_opcode_jump & 0x0F) | 0x80) << 8 ) + 0x0F;
pelem->long_address_jump = size;
}
else
{
pelem->short_address_jump = (char)size;
}
}
while ((pelem = pelem->prev) != 0);
return;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool CompileConditionInBrackets(char *pbuffer, pcompiled_condition pmas)
{
pcompiled_condition prev = NULL;
char level = 0;
char count = 0;
memset(pmas, 0, sizeof(str_compiled_condition));
while (pbuffer[0] == ' ') ++pbuffer;
if (!pbuffer[0]) return false;
while (pbuffer[0])
{
level = 0;
while (pbuffer[0] == ' ') ++pbuffer;
while (pbuffer[0] == '(')
{
++count;
++level;
++pbuffer;
while (pbuffer[0] == ' ') ++pbuffer;
}
pmas->brackets_left = level;
if (!CompileOneCondition(pbuffer, pmas))
return false;
level = 0;
while (pbuffer[0] == ' ') ++pbuffer;
while (pbuffer[0] == ')')
{
--count;
++level;
++pbuffer;
while (pbuffer[0] == ' ') ++pbuffer;
}
pmas->brackets_right = level;
switch (FindLogicCondition(pbuffer))
{
case 1:
{
if (pmas->short_opcode_jump & 1)
--pmas->short_opcode_jump;
else
++pmas->short_opcode_jump;
pmas->flags |= 0x1;
break;
}
case -1:
return false;
}
if (prev)
{
pmas->prev = prev;
pmas->prev->next = pmas;
}
prev = pmas;
pmas = (pcompiled_condition)((char *)pmas + pmas->size_compiled_code + sizeof(str_compiled_condition) - 1);
memset(pmas, 0, sizeof(str_compiled_condition));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -