Ae galera ant kore vitrix para vocês eu não sei se é 100% funcional mais o rodrigo dono do hell que min passo falo que é intão é né.
Download
Créditos: Rodrigo e eu
segunda-feira, 31 de outubro de 2011
Decompiler Fatality Gunz
Ae galera falei que ia faze e fiz o decompiler do fatality gunz aqui c1 e v2 para vocês usar o client e talz agr logo logo vo faze um tutorial do launcher, aproveitem o decompiler façam hackers, usem o client bom façam oq quizerem.
Download
Créditos: Pablo por encryptar o client
Download
Créditos: Pablo por encryptar o client
domingo, 30 de outubro de 2011
Anti Flood para site
Acredito que muitos já tem, mas para quem não tem ta aí :
Código PHP:
TIME() - 2){
// usuários que acessarem o site mais de uma vez em menos de 2 segundos serão redirecionados para está página
HEADER("location: /flood.html");
EXIT;
}
$_SESSION['last_session_request'] = TIME();
?>
Espero ter ajudado,
abraços.
Isso evitara que seu site caia.
Créditos: Ragezone BR Netheris
Código PHP:
TIME() - 2){
// usuários que acessarem o site mais de uma vez em menos de 2 segundos serão redirecionados para está página
HEADER("location: /flood.html");
EXIT;
}
$_SESSION['last_session_request'] = TIME();
?>
Espero ter ajudado,
abraços.
Isso evitara que seu site caia.
Créditos: Ragezone BR Netheris
Server Files Fatality Gunz
Pessoal vo posta aqui para vocês server files fatality gunz.
Não vo fala muita coisa porque to com pressa
Download
Esse server files mais ant kore convencional é incaivel por isso façam bom aproveito
Só para lembrar esse é o match server do the rox intão só vai funciona com a runable do fatality gunz por isso logo logo eu vo estar postando aqui o decompiler e um tutorial de como fazer um launcher para vocês poderem ultilizar o client do fatality gunz.
Pra quem sabe fazer decompiler os numeros são 4 128 249 182 76
Não vo fala muita coisa porque to com pressa
Download
Esse server files mais ant kore convencional é incaivel por isso façam bom aproveito
Só para lembrar esse é o match server do the rox intão só vai funciona com a runable do fatality gunz por isso logo logo eu vo estar postando aqui o decompiler e um tutorial de como fazer um launcher para vocês poderem ultilizar o client do fatality gunz.
Pra quem sabe fazer decompiler os numeros são 4 128 249 182 76
sábado, 29 de outubro de 2011
Web Site Fatality GunZ
sexta-feira, 28 de outubro de 2011
Visualizador de Personagens MAIET
Olá meus amores (MENTIRA),
Isto também reproduz animações para ir com os models.
Essa executavel ta em japonês, chinês, sei la, é uma monte de traço e inglês.
Pra ver sem os QUADRADO, baixe um pacote de idioma, que a vez de vc ver quadrado, vc ver japonês (MESMA MERDA PRA MIM, NÂO ENTENDO NADA).
Tenho uma imagem:

Tenho um video:
http://www.youtube.com/watch?v=KJ0BqdbAvfY&feature=player_embedded#!
Download:
http://www.mirrorcreator.com/files/1PFOL8ZJ/Maiet_Character_Viewer.rar_links
Senha: aulagunz_blasper
Créditos:
Dawson & Jacob
Blasper
Isto também reproduz animações para ir com os models.
Essa executavel ta em japonês, chinês, sei la, é uma monte de traço e inglês.
Pra ver sem os QUADRADO, baixe um pacote de idioma, que a vez de vc ver quadrado, vc ver japonês (MESMA MERDA PRA MIM, NÂO ENTENDO NADA).
Tenho uma imagem:

Tenho um video:
http://www.youtube.com/watch?v=KJ0BqdbAvfY&feature=player_embedded#!
Download:
http://www.mirrorcreator.com/files/1PFOL8ZJ/Maiet_Character_Viewer.rar_links
Senha: aulagunz_blasper
Créditos:
Dawson & Jacob
Blasper
quinta-feira, 27 de outubro de 2011
Exclusivo Itens do UnitedGzV1
Olá sou o Teeco vou posta aki para vcs
uma raridade varias pessoas tava pedindo pra min
entao resoolvir postar para vcs meus amores kk
pois e o seguintes são itens Editados que são
do client do United Gunz ..
Download : Cliquem aki !
Senha : aulagunz_teeco
Creditos : Teeco
Set Adidaas (Blue)(Verde)..
Olá sou o Teeco vou posta aki para voçês aki
do aula gunz 2 sets adidas um verde e um
azul editados pelo Germany do aula gunz
entao estarei postado aki ..
Verde

Blue

Download : Cliquem aki!
Senha : germany
Creditos : Germany e Teeco(pelo post)
domingo, 23 de outubro de 2011
Site FlameGunz v1 - CP no Site + AntiSQLInjection
Olá sou o Teeco vou posta aki depois de muito trabalho editando este site, do www.flamegunz.com v1. Aposto que vocês conhecem esse site,
mais aposto que não sabiam que tinha CP no menu.
Esse site foi editado por Charmape, Blasper, Shypers e Lon.
Veja a foto do site:

WebSite 100% AntiSQL
Leve e rápido.
Sem nenhum BUG.
AntiDDOS básico (Caso queira ativado, na index.php add o código)
CP no próprio site
Poderá add notícias no próprio site
Poderá add loja evento e donator no próprio site.
Informações do clã 100%
Informações do player 100%UserCP 100%
Clan emblema 100% anti sql
RESUMINDO, site fodão!
Download:Cliquem aki!
Senha: aulagunz_blasper
sábado, 22 de outubro de 2011
Como adicionar Meds ....
Hola ... por causa da semana do pan vo falar espanhol ..
Hola gente me puso aquí para ustedes una lección
de cómo añadir vídeo a sus medicamentos gunz
Video Aula
sábado, 15 de outubro de 2011
Set Nesk ...
Olá sou o Teeco vou posta aki no aula gunz
para vc um novo set que o meu colega fez
e pediu para eu postar aki e o set dele msm
bom mais esse set e diferente pq ele vcs
nao precisam add ele pois tem as partes
do elu. separadas para fica mais facil de colocar
os itens no gunz de voçês ..
Imagem :

Donload : Cliquem aki!
Scan : Cliquem aki!
Creditos : Nesk(iTench) por criar
Teeco(Leonard) por postar
Anti Lead (Compilada)
Olá galera sou o Teeco vou posta mais uma coisa
mt boa aki no aula gunz para vcs .. bom um colega meu
falo que era compilada eu testei e era msm entao resolvi
postar aki essa dll. que e um sonho de mt tem anti lead
no seu gunz (kkkkkkkkk) entao esta ae...
Download : Cliquem aki!
Creditos : Jacob(por criar)
Nesk(por compilar)
Teeco(por postar)
Coat Green
Olá galera sou o Teeco vou mais uma coisa
aki para vcs do blog aula gunz e um item que
vc ja teve ter conhecido que e o pink coat so que
o nosso amigo Nesk edito ela ae ela nao fico mais
rosa(pra quem e machista)ela fico verde e eu
gostei e resolvir posta aki para vcs blz ....
Vlw '
↓↓ Imagem ↓↓

Download : Cliquem aki!
Scan : Cliquem aki!
Creditos : Nesh(iTench)
By : Teeco
quinta-feira, 13 de outubro de 2011
Shotgun Edited...
Bom eu estava sem fazer nada entao resolvir fazer essa shotgun espero que gostem dela
Download: http://www.megaupload.com/?d=6VBGDGDZ
Creditos: SouthPark - Por Cria
E Charmape por postar.
Download: http://www.megaupload.com/?d=6VBGDGDZ
Creditos: SouthPark - Por Cria
E Charmape por postar.
terça-feira, 11 de outubro de 2011
Anti-Kore Convencional - Etroplus
Olá pessoal, dei uma distanciada muito grande de Gunz Online.
Acredito não voltar para área.
Mais se o ritmo ficar bom aqui na área.
Vou sempre está ajudando.
Isso que irei postar não pode se chamar uma proteção 100%.
Mais acredito que vai ajudar muito na "Área Gunz Online"
(Mantendo ela Viva)
Vamos lá
KSSWare Extended IP Filter + Export - Download
Acabei ganhando muito em cima desse programa, nós últimos tempos, aproveitei bastante da situação.
E agora estou postando e ensinando todos a usa-lo.
Ele foi muito útil, a um tempo atrás no servidor em que eu trabalhava.
Ele está há um bom tempo na área Gunz Online.
Mais eu sozinho, aprendi usa-lo.
Ele filtra pacotes, com uma certa "encrypitação", mais para isso é preciso saber configura-lo.
Vou postar nesse tópico o meu "Export Antigo".
Pois eu acharia muito injusto do trabalho que eu tive para faze-lo.
Aprendendo usar IpFilter:
Primeiro de tudo será necessário você efetuar o download do KSSWare Extended IP Filter.
Após você efetuar o download do arquivo, você irá extrair o arquivo .ZIP em algum lugar de referencia.
Depois disso, você irá abrir o IpFilter.exe.
Ficando assim:

Aprendendo a Exporta o arquivo .EIF
Depois de abrir o KSSWare Extended IP Filter, nós precisamos abrir o arquivo .EIF no programa.
Para isso você irá clicar em "File", e depois você irá clicar em "Import From...".
Sua imagem irá ficar assim.

Depois de clicar no Export, você irá clicar em "Abrir ou Open".
Ficando Assim:

Depois disso você irá clicar em "Configuration -> Drive -> Install".
OBS: O Import deve ser feito antes dessa ação, caso você ignore esse aviso, o IPFilter irá Dropar todos os Pacotes, causando a queda do "Acesso Remoto"

Após clicar em "Install", irá aparecer uma mensagem "Driver Installed"
Habilitando o Filtro de Pacotes:
E por ultimo você irá clicar em "Configuration -> Filter -> Start".
Após isso o filtro de pacotes de Kore, estará rolando.
Caso um dos Kores cadastrados, ataquem seu MatchServer.
Irá acrescentar um +1 em "Dropped"
E será criado um arquivo .TXT na pasta do IpFilter chamado ip_drop.txt.
Lá irá ter o log de ataques.
(Hora/Data/Ip do Atacante/Encrypitação do Kore/Porta)
OBS: Apenas na porta 6000, esse programa irá proteger. Portanto deixe seu server na porta padrão 6000
Não há necessidade de deixar o programa aberto, ele instala um drive, que fica rodando direto.
Após configurado uma vez, ele estará sempre funcionando
Agradecimentos:
Primeiramente para empresa "KSSWare Corporation", por esse excelente programa.
Segundo especialmente para mim mesmo "Etroplus", por desenvolver esse Tutorial, e adaptar esse "programa" para "Gunz Online".
Terceiro gostaria de pedir, aos leechers de plantão que mantivessem meus créditos nesse tutorial e no Programa.
ATT.Etroplus
Lifeer And Char (Postar aqui) '-'
Acredito não voltar para área.
Mais se o ritmo ficar bom aqui na área.
Vou sempre está ajudando.
Isso que irei postar não pode se chamar uma proteção 100%.
Mais acredito que vai ajudar muito na "Área Gunz Online"
(Mantendo ela Viva)
Vamos lá

KSSWare Extended IP Filter + Export - Download
Acabei ganhando muito em cima desse programa, nós últimos tempos, aproveitei bastante da situação.
E agora estou postando e ensinando todos a usa-lo.
Ele foi muito útil, a um tempo atrás no servidor em que eu trabalhava.
Ele está há um bom tempo na área Gunz Online.
Mais eu sozinho, aprendi usa-lo.
Ele filtra pacotes, com uma certa "encrypitação", mais para isso é preciso saber configura-lo.
Vou postar nesse tópico o meu "Export Antigo".
Pois eu acharia muito injusto do trabalho que eu tive para faze-lo.
Aprendendo usar IpFilter:
Primeiro de tudo será necessário você efetuar o download do KSSWare Extended IP Filter.
Após você efetuar o download do arquivo, você irá extrair o arquivo .ZIP em algum lugar de referencia.
Depois disso, você irá abrir o IpFilter.exe.
Ficando assim:
| Click this bar to view the full image. |

Aprendendo a Exporta o arquivo .EIF
Depois de abrir o KSSWare Extended IP Filter, nós precisamos abrir o arquivo .EIF no programa.
Para isso você irá clicar em "File", e depois você irá clicar em "Import From...".
Sua imagem irá ficar assim.
| Click this bar to view the full image. |

Depois de clicar no Export, você irá clicar em "Abrir ou Open".
Ficando Assim:
| Click this bar to view the full image. |

Depois disso você irá clicar em "Configuration -> Drive -> Install".
OBS: O Import deve ser feito antes dessa ação, caso você ignore esse aviso, o IPFilter irá Dropar todos os Pacotes, causando a queda do "Acesso Remoto"
| Click this bar to view the full image. |

Após clicar em "Install", irá aparecer uma mensagem "Driver Installed"
Habilitando o Filtro de Pacotes:
E por ultimo você irá clicar em "Configuration -> Filter -> Start".
Após isso o filtro de pacotes de Kore, estará rolando.
Caso um dos Kores cadastrados, ataquem seu MatchServer.
Irá acrescentar um +1 em "Dropped"
E será criado um arquivo .TXT na pasta do IpFilter chamado ip_drop.txt.
Lá irá ter o log de ataques.
(Hora/Data/Ip do Atacante/Encrypitação do Kore/Porta)
OBS: Apenas na porta 6000, esse programa irá proteger. Portanto deixe seu server na porta padrão 6000
Não há necessidade de deixar o programa aberto, ele instala um drive, que fica rodando direto.
Após configurado uma vez, ele estará sempre funcionando
Agradecimentos:
Primeiramente para empresa "KSSWare Corporation", por esse excelente programa.
Segundo especialmente para mim mesmo "Etroplus", por desenvolver esse Tutorial, e adaptar esse "programa" para "Gunz Online".
Terceiro gostaria de pedir, aos leechers de plantão que mantivessem meus créditos nesse tutorial e no Programa.
ATT.Etroplus
Lifeer And Char (Postar aqui) '-'
sexta-feira, 7 de outubro de 2011
MatchServer Drawze GunZ (Ant Rev + Vitrix)
Olá galera do Aula GunZ, sou o Charmape to postando aqui as
proteções do Drawze Gunz que o gaspar tinha
postado lá no fórum do Aula antigamente de acontecer
esse desastre com o aula de apagar o blog mais o importante é que recuperamos...
O download esta aki espero que gostem
Download : Cliquem aqui
Senha: aulagunz_gaspar
Creditos: Gaspar Por criar
Créditos: Charmape Por postar
Créditos: Charmape Por postar
Adicionando novos comandos
Este código é para você adicionar comandos para o seu gunz usando a classe ZChatCmdManager.
Isto é para programadores só, eu não vou responder a perguntas newbie.
ZChat.h
ZChatCmdManager.cpp
Como eu disse, isso é para programadores, e não para novatos... Por exemplo, se você digitar /fechar_jogo o jogo se fechará. E se vc digitar /teste apenas os GMs e ADMs conseguirão fazer o que vc irá programar....
Créditos:
Blasper - Por postar
Espanish - Por publicar o código
Isto é para programadores só, eu não vou responder a perguntas newbie.
ZChatCmdManager.h
#pragma once class ZChatCmdManager { public: void ZChatCmdManager::AddCommand(int, char*, void (__cdecl *)( char *, int, char ** ), ULONG, int, int, bool, char*, char*); };#pragma once #include "ZChatCmdManager.h" class ZChat // 0x1c7c { public: void *vTable; ZChatCmdManager m_CmdManager; // +0x4(0x1c) ULONG m_nLastInputTime; // +0x20(0x4) int m_nSameMsgCount; // +0x24(0x4) char m_nLastInputMsg[512]; // +0x28(0x200) ULONG m_nLastAbuseTime; // +0x228(0x4) int m_nAbuseCounter; // +0x22c(0x4) char m_szWhisperLastSender[64]; // +0x230(0x40) char Unknow[6668]; };#include "zchatcmdmanager.h" void ZChatCmdManager::AddCommand( int nID, char *szName, void(__cdecl *fnProc)( char *, int, char ** ), ULONG flag, int nMinArgs, int nMaxArgs, bool bRepeatEnabled, char *szUsage, char *szHelp ) { __asm { push szHelp push szUsage push bRepeatEnabled push nMaxArgs push nMinArgs push flag push fnProc push szName push nID mov ecx, this mov eax, 0x431170 //! 08 July Address call eax } }Agora vou postar o código para você usar esta função:#define ZGetGameInterface() ((DWORD(*)())0x4AD790)() void ChatCmd_Close_Game( char *line, int argc, char *argv[] ) { ExitProcess(0); } void ChatCmd_ForADMandGMonly( char *line, int argc, char *argv[] ) { ExitProcess(0); } void ZComandos() { //! You will need to have ZGetGameInterface function while( !ZGetGameInterface() ) Sleep(50); ZChat *m_pChat = (ZChat*)(ZGetGameInterface() + 0x380); m_pChat->m_CmdManager.AddCommand( 0, "fechar_jogo", ChatCmd_Close_Game, 0xF, -1, -1, 1, "/close_game", (char*)0x62286C ); //! For ADM and GM Only, because flag is 0x80 m_pChat->m_CmdManager.AddCommand( 0, "teste", ChatCmd_ForADMandGMonly, 0x80, -1, -1, 1, "/test", (char*)0x62286C ); }Como eu disse, isso é para programadores, e não para novatos... Por exemplo, se você digitar /fechar_jogo o jogo se fechará. E se vc digitar /teste apenas os GMs e ADMs conseguirão fazer o que vc irá programar....
Créditos:
Blasper - Por postar
Espanish - Por publicar o código
MRS Custom Encrypter Avançado + Source
Olá,
Este é um encriptação avançado criado por Steven,
Com ele você pode encriptar os seus arquivos .exe do GUNZ...
Você pode remover a encriptação, altera-la e cria-la.
Imagens:
Este é um encriptação avançado criado por Steven,
Com ele você pode encriptar os seus arquivos .exe do GUNZ...
Você pode remover a encriptação, altera-la e cria-la.
Server Keeper Auto Inject
Olá,
Este foi o primeiro programa criado por mhmd135.
Um server keeper com um designer bonito e com um AUTO INJECT de DLL.
Download: http://www.mediafire.com/?zgnb9d9nf99fzfe
No VírusTotal diz que contém vírus, mais baixei no meu PC e o AntiVírus não acusou de vírus e estou usando a um bom tempo, e não aconteceu absolutamente nada...
Créditos:
Blasper - Por postar
mhmd135 - Por desenvolver o programa
mhmd135 - Por desenvolver o programa
Galaxy GunZ's website

Como usar?
Coloque o site em sua pasta www ou htdocs, e edite "includes / class_config.php"
Se der este error...
Ficando "Call to undefined mssql_connect ()" erro?
Vusion gravou um pequeno vídeo.
Código:
ntwdblib.dll: http://www.mediafire.com/?g8g2bf2tgtd67u3
1.Put DLL no PHP6, Apache 2.2, bin (encontrado no "Apache 2.2").
2.Abra o php.ini e remova o ";" antes dessas linhas:
extension = php_ming.dll
extension = php_mssql.dll
3.Você reiniciar o servidor apache.
-------------------------------------------------------
Link para download: R.A.TSenha é Vusion
Créditos:
Error404 - Projetando a principal base como um site flyff.
Lifeles5 - As imagens sob a juntar-me guia
Dylan - tela de carregamento (Usada como o etc banner)
Militar - Reorganizando coisas.
SuperWaffle - HTML / CSS.
Aviador - deslizante Ranking de css / js codificação.
Zewa - Fixação do menu drop.
SuperWaffle & Lifeles5 - Por serem os professores impressionante.
Hussain - Por ser um boyke swagga matar todos eles.
Vusion - Para o resto, como na codificação PHP.
Eu - Para postar e traduzir na RGZBR.
Lifeer:postar aqui
obs:se vc nao conseguiu ver toda a postagem veja direto da ragezone clique aqui
bye
RoboGuard v3.7 - Source
Isto são para programadores, caso você seja um novato, tente compila-lo e mandar pelo XAT que nós postamos no AG compilado.
Main.CPP
DETOUR FOLDER
Credits to LanceVorgin
Detour/CDetour.h
Detour/CDetour.cpp
Detour/CByteArray.h
Detour/CDetourDis.cpp
Detour/CDetourDis.h
--------------------------------------------------------------------------------------------------------------
Todas as funções e endereços
Usado para codificação em MatchServer
Exemplo:
sourcefiles.txt
Créditos:Main.CPP
Code:
#define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include#include #include #include #include #include #include #include using namespace std; #include "Detour/CDetour.h" #define ONCE( var ) static bool var = false; if(! var ){ var = true; bool CompareByteArrays(BYTE* data1, BYTE* data2, int len){ // If both are null, they're equal if (data1==NULL && data2==NULL) return true; // If either but not both are null, they're not equal if (data1==NULL || data2==NULL) return false; for (int i=0; i < len; i++){ if (data1[i] != data2[i]) if(data2[i] != 0xEE) return false; } return true; } DWORD m_CodeBase = 0x00400000; DWORD m_CodeLength = 0x001C5000; DWORD SigSearch(BYTE* Signature, int SigLength) { BYTE* test = NULL; for(unsigned int i = 0; i < (m_CodeLength-SigLength); i++) { if(CompareByteArrays((BYTE*)((DWORD)m_CodeBase + i), Signature,SigLength)) { return (DWORD)m_CodeBase + i; } } return 0; } //ServerAnnounce BYTE ServerAnnounceSignature[] = {0X64,0XA1,0X00,0X00,0X00,0X00,0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X8B,0X44,0X24,0XEE,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X53,0X56,0X57,0X50,0X68,0X92,0X01,0X00,0X00,}; DWORD ServerAnnounceSignatureOffset = SigSearch(ServerAnnounceSignature, 34); //OnAdminAnnounce BYTE OnAdminAnnounceSignature[] = {0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X64,0XA1,0X00,0X00,0X00,0X00,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X81,0XEC,0X10,0X01,0X00,0X00,}; DWORD OnAdminAnnounceSignatureOffset = SigSearch(OnAdminAnnounceSignature, 27); //OnStageStart BYTE OnStageStartSignature[] = {0X55,0X8B,0XEC,0X83,0XE4,0XF8,0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X81,0XEC,0X30,0X04,0X00,0X00,}; DWORD OnStageStartSignatureOffset = SigSearch(OnStageStartSignature, 27); //OnGameKill BYTE OnGameKillSignature[] = {0X64,0XA1,0X00,0X00,0X00,0X00,0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X8B,0X44,0X24,0X14,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X83,0XEC,0X14,0X53,0X55,0X56,0X50,}; DWORD OnGameKillSignatureOffset = SigSearch(OnGameKillSignature, 32); //OnUserWhisper BYTE OnUserWhisperSignature[] = {0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X83,0XEC,0X10,0X8B,0X44,0X24,0X24,0X56,}; DWORD OnUserWhisperSignatureOffset = SigSearch(OnUserWhisperSignature, 23); //OnChannelChat BYTE OnChannelChatSignature[] = {0XE9,0XEE,0XEE,0XEE,0XEE,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0X8B,0X44,0X24,0X08,0X56,0X57,0X8B,0XF1,0X50,}; DWORD OnChannelChatSignatureOffset = SigSearch(OnChannelChatSignature, 25); //OnStageChat BYTE OnStageChatSignature[] = {0X53,0X8B,0X5C,0X24,0X0C,0X55,0X8B,0X6C,0X24,0X0C,0X56,0X57,0X8B,0X7C,0X24,}; DWORD OnStageChatSignatureOffset = SigSearch(OnStageChatSignature, 15); //OnClanMessage BYTE OnClanMessageSignature[] = {0X6A,0XFF,0X68,0XEE,0XEE,0XEE,0XEE,0X64,0XA1,0X00,0X00,0X00,0X00,0X50,0X64,0X89,0X25,0X00,0X00,0X00,0X00,0X81,0XEC,0X14,0X03,0X00,0X00,}; DWORD OnClanMessageSignatureOffset = SigSearch(OnClanMessageSignature, 27); //OnStageCreate BYTE OnStageCreateSignature[] = {0X83,0XEC,0X10,0X53,0X8B,0X5C,0X24,0X18,0X56,0X57,0X53,0X8B,0XF1,0XE8,0XEE,0XEE,0XEE,0XEE,0X8B,0XF8,0X85,0XFF,}; DWORD OnStageCreateSignatureOffset = SigSearch(OnStageCreateSignature, 22); HMODULE g_hLocalModule = NULL; DWORD g_dwUnloadRetAddr = 0; __declspec(naked) void UnloadProc(){ __asm push g_hLocalModule __asm push g_dwUnloadRetAddr __asm jmp dword ptr [FreeLibrary] } struct MUID{ long firstID; long secondID; }MYUID; MUID* Char1ID = new MUID(); MUID* Char2ID = new MUID(); MUID* StageID = new MUID(); long n; long uidChar; long uidClanAdmin; long uidStage; char pszMessage[128]; //Announcement typedef void(__cdecl* ServerAnnounceFunc)(MUID* uidChar,char*); ServerAnnounceFunc ServerAnnounce = (ServerAnnounceFunc)ServerAnnounceSignatureOffset; //Mega PowerLevel Patch DWORD OnGameKill = OnGameKillSignatureOffset; CDetour OnGameKillDet; void __stdcall OnGameKillHook(MUID* uidChar,MUID* uidChar2){ Sleep(800); } //Admin Announce Buffer Patch DWORD OnAdminAnnounce = OnAdminAnnounceSignatureOffset; // 0x00416370; CDetour OnAdminAnnounceDet; void __stdcall OnAdminAnnounceHook(MUID* uidChar,char* pszMessage,unsigned long unknown){ if(strlen(pszMessage)>128) { pszMessage = "\0"; } if(unknown = 1){ unknown = 0; } } //Whisper Buffer Patch DWORD OnWhisper = OnUserWhisperSignatureOffset; CDetour OnWhisperDet; void __stdcall OnWhisperHook(MUID* uidChar,char* pszSenderName,char* pszTargetName,char* pszMessage){ if(strlen(pszMessage)>128) { pszMessage = "I have attempted to crash you. Please report me."; } } //Channel Buffer Patch DWORD OnChannelChat = OnChannelChatSignatureOffset; CDetour OnChannelChatDet; void __stdcall OnChannelChatHook(MUID* uidChar,MUID* uidChannel,char* pszMessage){ if(strlen(pszMessage)>128) { pszMessage = "I have attempted to crash the channel. Please report me."; } } //Stage Buffer Patch DWORD OnStageChat = OnStageChatSignatureOffset; CDetour OnStageChatDet; void __stdcall OnStageChatHook(MUID* uidChar,MUID* uidStage,char* pszMessage){ if(strlen(pszMessage)>128) { pszMessage = "I have attempted to crash the stage. Please report me."; } } //Clan Buffer Patch DWORD OnClanMsg = OnClanMessageSignatureOffset; CDetour OnClanMsgDet; void __stdcall OnClanMsgHook(MUID* uidChar, char* pszMessage){ if(strlen(pszMessage)>128){ pszMessage = "\0"; } } void Initialize(){ //Mega PowerLevel Patch OnGameKillDet.Detour((BYTE*)OnGameKill, (BYTE*)OnGameKillHook, true); OnGameKillDet.Apply(); //Admin Announce Patch OnAdminAnnounceDet.Detour((BYTE*)OnAdminAnnounce, (BYTE*)OnAdminAnnounceHook, true); OnAdminAnnounceDet.Apply(); //Whisper Buffer Patch OnWhisperDet.Detour((BYTE*)OnWhisper, (BYTE*)OnWhisperHook, true); OnWhisperDet.Apply(); //Channel Buffer Patch OnChannelChatDet.Detour((BYTE*)OnChannelChat, (BYTE*)OnChannelChatHook, true); OnChannelChatDet.Apply(); //Stage Buffer Patch OnStageChatDet.Detour((BYTE*)OnStageChat, (BYTE*)OnStageChatHook, true); OnStageChatDet.Apply(); MessageBox(0,"GZRoboGuard v3.7 Injected!","Coded by OneWhoSighs",MB_ICONINFORMATION); } /********************************************************************************/ //Remove the detours/patches when unloaded void Shutdown(){ //Mega PowerLevel Patch OnGameKillDet.Remove(); //Admin Announce Patch OnAdminAnnounceDet.Remove(); //Whisper Buffer Patch OnWhisperDet.Remove(); //Channel Buffer Patch OnChannelChatDet.Remove(); //Stage Buffer Patch OnStageChatDet.Remove(); } /********************************************************************************/ bool WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved){ if(dwReason == DLL_PROCESS_ATTACH){ ONCE(bHasLoaded) g_hLocalModule = hModule; Initialize(); } } else if(dwReason == DLL_PROCESS_DETACH){ ONCE(bHasShutdown) Shutdown(); } } return true; }
Credits to LanceVorgin
Detour/CDetour.h
Code:
/***************************** * Universal Detour Class * * v2.0 * ****************************** * By LanceVorgin * ****************************** * UNI owns all * *****************************/ #pragma once #include "CByteArray.h" typedef void* (__cdecl* CDetourOrg_Func)( ... ); class CDetour { public: static int Applied(); static int Removed(); static void InitRand(); private: static int g_iApplied; static int g_iRemoved; static void* __cdecl NullOrgFunc( ... ); static CDetourOrg_Func NullOrg; public: CDetour(); ~CDetour(); bool Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bAutoReturn = false, bool bNoRegs = false, bool bPolymorphic = false, int iArgsOverride = -1, int iBytesToOverwrite = -1); bool Detour(LPCSTR lpLibraryName, LPCSTR lpProcName, BYTE* pFuncToCall, bool bAutoReturn = false, bool bNoRegs = false, bool bPolymorphic = false, int iArgsOverride = -1, int iBytesToOverwrite = -1); bool Apply(); bool Remove(); bool IsReady(); bool IsApplied(); BYTE* GetAddr(); BYTE* GetFuncToCall(); void SetFuncToCall(BYTE* pFuncToCall); BYTE* GetRetAddress(); BYTE* GetGateRetAddress(); void SetGateRetAddress(BYTE* pGateRetAddress); BYTE* GetThisPtr(); void SetThisPtr(BYTE* pThisPtr); void NoSetThisPtr(bool bNoSetThisPtr); void Ret(bool bReturnToOriginal); CDetourOrg_Func Org; private: void Deconstruct(); void FreeBuffers(); bool Generate(); int GetDetourSize(); bool GenerateDetour(CByteArray& Buffer, BYTE* pBase, BYTE* pTarget, int iFinalSize = -1); bool WriteToAddr(BYTE* pBuffer, int iSize); bool m_bReady; bool m_bApplied; bool m_bAutoReturn; bool m_bNoRegs; bool m_bPolymorphic; int m_iArgsOverride; int m_iBytesToOverwrite; BYTE* m_pAddr; BYTE* m_pFuncToCall; BYTE m_ubDetourType; int m_iDetourSize; BYTE* m_pOrgAfterDetour; BYTE* m_pDetourBuf; BYTE* m_pOrgBuf; BYTE* m_pGateBuf; BYTE* m_pOrgGateBuf; bool m_bDontReplaceOrgClassInstance; BYTE* m_pGateStack; BYTE* m_pGateRealRet; bool m_bReturnToOriginal; BYTE* m_pAutoReturnEndStack; BYTE* m_pRetAddress; BYTE* m_pClassInstance; BYTE* m_pOrgReturnAddress; BYTE* m_pOrgStack; }; class CSimpleDetour { public: static int Applied(); static int Removed(); private: static int g_iApplied; static int g_iRemoved; public: CSimpleDetour(); ~CSimpleDetour(); bool Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bExecuteOverwrittenOps = true, int iBytesToOverwrite = 0); bool Apply(); bool Remove(); bool IsReady(); bool IsApplied(); BYTE* GetAddr(); BYTE* GetFuncToCall(); void SetFuncToCall(BYTE* pFuncToCall); BYTE* GetRetAddress(); void Ret(bool bReturnToOriginal); private: void Deconstruct(); void FreeBuffers(); bool Generate(); bool WriteToAddr(BYTE* pBuffer, int iSize); bool m_bReady; bool m_bApplied; bool m_bExecuteOverwrittenOps; int m_iBytesToOverwrite; BYTE* m_pAddr; BYTE* m_pFuncToCall; int m_iDetourSize; BYTE* m_pOrgAfterDetour; BYTE* m_pDetourBuf; BYTE* m_pOrgBuf; BYTE* m_pGateBuf; BYTE* m_pRetAddress; };Code:
/***************************** * Universal Detour Class * * v2.0 * ****************************** * By LanceVorgin * ****************************** * UNI owns all * *****************************/ /* All credit for CDetourDis goes to Micro$oft GG CB for the ByteArray idea - asshole :P License: I, LanceVorgin, allow you to use these classes in any of your projects under the following conditions: * My name appears in your readme and credits along with the fact that my CDetour was used * You do not take credit for CDetour That's all. GPL, closed source, private, it's all good :) Detour Settings: bAutoReturn - If true, after hookfunc is called, the original function will be called with the original args - unless Ret(false) has been called bNoRegs - If true, detour does not modify any registers besides esp. Use for fastcalls / other funcs that take params in regs (evil msvc 2k5) (usually, detour will save ecx and reset it in Org for class funcs) bPolymorphic - If false the detour is a jmp. If true the detour is randomiezed and impliments a random number. These are alot bigger than 5 bytes iArgsOverride - Usually, the hookfunc is defined as identical to the function hooked in both args and calling convention. With this set, the stack will be modified after the hookfunc is called as if an stdcall with x args has been called. Useful if you have a stdcall func with like 10 args that you don't give a shit about (you'd otherwise have to have 10 junk args on your hookfunc) iBytesToOverwrite - Overrides the automatic reassembler. Todo: * Add setproxy * Add Polymorph Dimension: replace push 8D 64 24 FC lea esp,[esp-4] C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h 83 EC 04 sub esp,4 C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h */ #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include#include #include "CDetourDis.h" #include "CDetour.h" void* CDetour::NullOrgFunc( ... ){ return NULL; } CDetourOrg_Func CDetour::NullOrg = (CDetourOrg_Func)CDetour::NullOrgFunc; int CDetour::g_iApplied = 0; int CDetour::g_iRemoved = 0; int CDetour::Applied(){ return g_iApplied; } int CDetour::Removed(){ return g_iRemoved; } void CDetour::InitRand(){ srand(GetTickCount()); } CDetour::CDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; m_bApplied = false; Deconstruct(); }; CDetour::~CDetour(){ Deconstruct(); }; void CDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); Org = NullOrgFunc; m_bAutoReturn = false; m_bNoRegs = false; m_bPolymorphic = false; m_iArgsOverride = -1; m_iBytesToOverwrite = -1; m_pAddr = NULL; m_pFuncToCall = NULL; m_ubDetourType = 0; m_iDetourSize = 0; m_pOrgAfterDetour = NULL; m_bDontReplaceOrgClassInstance = false; m_bReturnToOriginal = false; m_pGateStack = NULL; m_pGateRealRet = NULL; m_pAutoReturnEndStack = NULL; m_pRetAddress = NULL; m_pClassInstance = NULL; m_pOrgReturnAddress = NULL; m_pOrgStack = NULL; } void CDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; if(m_pOrgGateBuf) delete[] m_pOrgGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; } bool CDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bAutoReturn = bAutoReturn; m_bNoRegs = bNoRegs; m_bPolymorphic = bPolymorphic; m_iArgsOverride = iArgsOverride; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CDetour::Detour(LPCSTR lpLibraryName, LPCSTR lpProcName, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ HMODULE hModule = LoadLibrary(lpLibraryName); if(!hModule) return false; BYTE* pTargetAddress = (BYTE*)GetProcAddress(hModule, lpProcName); if(!pTargetAddress) return false; return Detour(pTargetAddress, pFuncToCall, bAutoReturn, bNoRegs, bPolymorphic, iArgsOverride, iBytesToOverwrite); } bool CDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CDetour::IsReady(){ return m_bReady; } bool CDetour::IsApplied(){ return m_bApplied; } BYTE* CDetour::GetAddr(){ return m_pAddr; } BYTE* CDetour::GetFuncToCall(){ return m_pFuncToCall; } void CDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CDetour::GetRetAddress(){ return m_pRetAddress; } BYTE* CDetour::GetGateRetAddress(){ return m_pGateRealRet; } void CDetour::SetGateRetAddress(BYTE* pGateRetAddress){ m_pGateRealRet = pGateRetAddress; } BYTE* CDetour::GetThisPtr(){ return m_pClassInstance; } void CDetour::SetThisPtr(BYTE* pThisPtr){ m_pClassInstance = pThisPtr; } void CDetour::NoSetThisPtr(bool bNoSetThisPtr){ m_bDontReplaceOrgClassInstance = bNoSetThisPtr; } void CDetour::Ret(bool bReturnToOriginal){ m_bReturnToOriginal = bReturnToOriginal; } int CDetour::GetDetourSize(){ CByteArray Buffer; if(!GenerateDetour(Buffer, 0, 0)) return -1; return Buffer.Size(); } #define RAND_DETOUR_TYPES 9 bool CDetour::GenerateDetour(CByteArray& Buffer, BYTE* pBase, BYTE* pTarget, int iFinalSize){ Buffer.Clear(); if(m_ubDetourType > RAND_DETOUR_TYPES) return false; DWORD dwTmpRnd = ((m_ubDetourType != 0) ? (rand() | (rand() << 16)) : 0); switch(m_ubDetourType){ case 0: Buffer += (BYTE)0xE9; //jmp Buffer += (DWORD)(pTarget - pBase - 5); break; case 1: case 2: case 3: Buffer += (BYTE)0x68; //push Buffer += (DWORD)dwTmpRnd; Buffer += (BYTE)0x81; //xor dword ptr [esp] Buffer += (BYTE)0x34; Buffer += (BYTE)0x24; Buffer += (DWORD)((DWORD)pTarget ^ dwTmpRnd); break; case 4: case 5: case 6: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(((DWORD)pTarget << ((BYTE)dwTmpRnd & 31)) | ((DWORD)pTarget >> (32 - ((BYTE)dwTmpRnd & 31)))); Buffer += (BYTE)0xC1; //ror dword ptr [esp], Buffer += (BYTE)0x0C; Buffer += (BYTE)0x24; Buffer += (BYTE)dwTmpRnd; break; case 7: case 8: case 9: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(pTarget - dwTmpRnd); Buffer += (BYTE)0x81; //add dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; Buffer += (DWORD)dwTmpRnd; break; } switch(m_ubDetourType){ case 1: case 4: case 7: Buffer += (BYTE)0xC3; //ret break; case 2: case 5: case 8: Buffer += (BYTE)0xC2; //retn Buffer += (WORD)0; break; case 3: case 6: case 9: Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xC4; Buffer += (BYTE)0x04; Buffer += (BYTE)0xFF; //jmp dword ptr [esp-4] Buffer += (BYTE)0x64; Buffer += (BYTE)0x24; Buffer += (BYTE)0xFC; break; } if(iFinalSize != -1){ if(iFinalSize < (int)Buffer.Size()) return false; while((int)Buffer.Size() < iFinalSize) Buffer += (BYTE)OP_NOP; } return true; } bool CDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- if(m_bPolymorphic) m_ubDetourType = (BYTE)(rand() % RAND_DETOUR_TYPES) + 1; else m_ubDetourType = 0; int iRawDetourSize = GetDetourSize(); if(iRawDetourSize == -1) return false; if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize){ if(!m_bPolymorphic) return false; for(m_ubDetourType = 1; m_ubDetourType <= RAND_DETOUR_TYPES; m_ubDetourType++){ iRawDetourSize = GetDetourSize(); if(iRawDetourSize <= m_iBytesToOverwrite) break; } if(m_ubDetourType > RAND_DETOUR_TYPES) return false; } //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect((void*)m_dwAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); if(!m_bNoRegs){ Buffer += (BYTE)0x89; //mov dword ptr, ecx Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; } Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0x83; //sub esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; int iCallOrgEndOffsetIndex = -1; int iCallOrgEndOffset = -1; if(m_bAutoReturn){ //Buffer += (BYTE)0xCC; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)1; Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)0; Buffer += (BYTE)0x74; //je iCallOrgEndOffsetIndex = Buffer + (BYTE)0; if(m_iArgsOverride <= 0){ Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; } Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pOrgGateBuf; if(m_iArgsOverride > 0){ iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateRealRet; } }else if(m_iArgsOverride > 0){ Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pFuncToCall; } m_pGateBuf = Buffer.Copy(); if(m_bAutoReturn) *(BYTE*)&m_pGateBuf[iCallOrgEndOffsetIndex] = (BYTE)iCallOrgEndOffset; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pOrgReturnAddress; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; Buffer += (BYTE)0xC7; //mov dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; int iOrgReturnAddressIndex = Buffer + (DWORD)0; if(!m_bNoRegs){ Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; Buffer += (BYTE)0x0F; //cmove ecx, dword ptr Buffer += (BYTE)0x44; Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; //Buffer += (BYTE)0x8B; //mov ecx, dword ptr //Buffer += (BYTE)0x0D; //Buffer += (DWORD)&m_pClassInstance; } //----- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect((void*)m_pAddr, m_iDetourSize, pOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; m_pOrgAfterDetour = pbSrc; //----- if(!(*pbLastOp == OP_BRK || *pbLastOp == OP_NOP)){ //align [end of function] Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgAfterDetour; } int iOrgReturnAddressOffset = Buffer.Peek(); Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgReturnAddress; m_pOrgGateBuf = Buffer.Copy(); //----- *(DWORD*)&m_pOrgGateBuf[iOrgReturnAddressIndex] = (DWORD)&m_pOrgGateBuf[iOrgReturnAddressOffset]; BYTE* pbDst = &m_pOrgGateBuf[iOverwrittenOpsIndex]; pbSrc = (BYTE*)m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- if(!GenerateDetour(Buffer, m_pAddr, m_pGateBuf, m_iDetourSize)) return false; m_pDetourBuf = Buffer.Copy(); Buffer.Clear(); //----------------- Org = (CDetourOrg_Func)m_pOrgGateBuf; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; } int CSimpleDetour::g_iApplied = 0; int CSimpleDetour::g_iRemoved = 0; int CSimpleDetour::Applied(){ return g_iApplied; } int CSimpleDetour::Removed(){ return g_iRemoved; } CSimpleDetour::CSimpleDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; Deconstruct(); }; CSimpleDetour::~CSimpleDetour(){ Deconstruct(); }; void CSimpleDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); m_iBytesToOverwrite = 0; m_pAddr = NULL; m_pFuncToCall = NULL; m_iDetourSize = 0; m_pRetAddress = 0; } void CSimpleDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; } bool CSimpleDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bExecuteOverwrittenOps, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bExecuteOverwrittenOps = bExecuteOverwrittenOps; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CSimpleDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false;; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CSimpleDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CSimpleDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CSimpleDetour::IsReady(){ return m_bReady; } bool CSimpleDetour::IsApplied(){ return m_bApplied; } BYTE* CSimpleDetour::GetAddr(){ return m_pAddr; } BYTE* CSimpleDetour::GetFuncToCall(){ return m_pFuncToCall; } void CSimpleDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CSimpleDetour::GetRetAddress(){ return m_pRetAddress; } bool CSimpleDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- Buffer.Clear(); Buffer += (BYTE)0xE8; //call int iDetourOffsetIndex = Buffer + (DWORD)0; BYTE* pRawDetourBuf = Buffer.Copy(); int iRawDetourSize = Buffer.Peek(); if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize) return false; //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect(m_pAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; //----------------- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect(m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; //----- Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pRetAddress; m_pGateBuf = Buffer.Copy(); //----------------- BYTE* pbDst = &m_pGateBuf[iOverwrittenOpsIndex]; pbSrc = m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- *(int*)&pRawDetourBuf[iDetourOffsetIndex] = m_pGateBuf - m_pAddr - 5; m_pDetourBuf = new BYTE[m_iDetourSize]; memset(m_pDetourBuf, OP_NOP, m_iDetourSize); memcpy(m_pDetourBuf, pRawDetourBuf, iRawDetourSize); delete[] pRawDetourBuf; pRawDetourBuf = NULL; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_dwAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; }
Code:
/***************************** * Universal Detour Class * * v2.0 * ****************************** * By LanceVorgin * ****************************** * UNI owns all * *****************************/ /* All credit for CDetourDis goes to Micro$oft GG CB for the ByteArray idea - asshole :P License: I, LanceVorgin, allow you to use these classes in any of your projects under the following conditions: * My name appears in your readme and credits along with the fact that my CDetour was used * You do not take credit for CDetour That's all. GPL, closed source, private, it's all good :) Detour Settings: bAutoReturn - If true, after hookfunc is called, the original function will be called with the original args - unless Ret(false) has been called bNoRegs - If true, detour does not modify any registers besides esp. Use for fastcalls / other funcs that take params in regs (evil msvc 2k5) (usually, detour will save ecx and reset it in Org for class funcs) bPolymorphic - If false the detour is a jmp. If true the detour is randomiezed and impliments a random number. These are alot bigger than 5 bytes iArgsOverride - Usually, the hookfunc is defined as identical to the function hooked in both args and calling convention. With this set, the stack will be modified after the hookfunc is called as if an stdcall with x args has been called. Useful if you have a stdcall func with like 10 args that you don't give a shit about (you'd otherwise have to have 10 junk args on your hookfunc) iBytesToOverwrite - Overrides the automatic reassembler. Todo: * Add setproxy * Add Polymorph Dimension: replace push 8D 64 24 FC lea esp,[esp-4] C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h 83 EC 04 sub esp,4 C7 04 24 78 56 34 12 mov dword ptr [esp], 12345678h */ #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include#include #include "CDetourDis.h" #include "CDetour.h" void* CDetour::NullOrgFunc( ... ){ return NULL; } CDetourOrg_Func CDetour::NullOrg = (CDetourOrg_Func)CDetour::NullOrgFunc; int CDetour::g_iApplied = 0; int CDetour::g_iRemoved = 0; int CDetour::Applied(){ return g_iApplied; } int CDetour::Removed(){ return g_iRemoved; } void CDetour::InitRand(){ srand(GetTickCount()); } CDetour::CDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; m_bApplied = false; Deconstruct(); }; CDetour::~CDetour(){ Deconstruct(); }; void CDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); Org = NullOrgFunc; m_bAutoReturn = false; m_bNoRegs = false; m_bPolymorphic = false; m_iArgsOverride = -1; m_iBytesToOverwrite = -1; m_pAddr = NULL; m_pFuncToCall = NULL; m_ubDetourType = 0; m_iDetourSize = 0; m_pOrgAfterDetour = NULL; m_bDontReplaceOrgClassInstance = false; m_bReturnToOriginal = false; m_pGateStack = NULL; m_pGateRealRet = NULL; m_pAutoReturnEndStack = NULL; m_pRetAddress = NULL; m_pClassInstance = NULL; m_pOrgReturnAddress = NULL; m_pOrgStack = NULL; } void CDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; if(m_pOrgGateBuf) delete[] m_pOrgGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; m_pOrgGateBuf = NULL; } bool CDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bAutoReturn = bAutoReturn; m_bNoRegs = bNoRegs; m_bPolymorphic = bPolymorphic; m_iArgsOverride = iArgsOverride; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CDetour::Detour(LPCSTR lpLibraryName, LPCSTR lpProcName, BYTE* pFuncToCall, bool bAutoReturn, bool bNoRegs, bool bPolymorphic, int iArgsOverride, int iBytesToOverwrite){ HMODULE hModule = LoadLibrary(lpLibraryName); if(!hModule) return false; BYTE* pTargetAddress = (BYTE*)GetProcAddress(hModule, lpProcName); if(!pTargetAddress) return false; return Detour(pTargetAddress, pFuncToCall, bAutoReturn, bNoRegs, bPolymorphic, iArgsOverride, iBytesToOverwrite); } bool CDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CDetour::IsReady(){ return m_bReady; } bool CDetour::IsApplied(){ return m_bApplied; } BYTE* CDetour::GetAddr(){ return m_pAddr; } BYTE* CDetour::GetFuncToCall(){ return m_pFuncToCall; } void CDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CDetour::GetRetAddress(){ return m_pRetAddress; } BYTE* CDetour::GetGateRetAddress(){ return m_pGateRealRet; } void CDetour::SetGateRetAddress(BYTE* pGateRetAddress){ m_pGateRealRet = pGateRetAddress; } BYTE* CDetour::GetThisPtr(){ return m_pClassInstance; } void CDetour::SetThisPtr(BYTE* pThisPtr){ m_pClassInstance = pThisPtr; } void CDetour::NoSetThisPtr(bool bNoSetThisPtr){ m_bDontReplaceOrgClassInstance = bNoSetThisPtr; } void CDetour::Ret(bool bReturnToOriginal){ m_bReturnToOriginal = bReturnToOriginal; } int CDetour::GetDetourSize(){ CByteArray Buffer; if(!GenerateDetour(Buffer, 0, 0)) return -1; return Buffer.Size(); } #define RAND_DETOUR_TYPES 9 bool CDetour::GenerateDetour(CByteArray& Buffer, BYTE* pBase, BYTE* pTarget, int iFinalSize){ Buffer.Clear(); if(m_ubDetourType > RAND_DETOUR_TYPES) return false; DWORD dwTmpRnd = ((m_ubDetourType != 0) ? (rand() | (rand() << 16)) : 0); switch(m_ubDetourType){ case 0: Buffer += (BYTE)0xE9; //jmp Buffer += (DWORD)(pTarget - pBase - 5); break; case 1: case 2: case 3: Buffer += (BYTE)0x68; //push Buffer += (DWORD)dwTmpRnd; Buffer += (BYTE)0x81; //xor dword ptr [esp] Buffer += (BYTE)0x34; Buffer += (BYTE)0x24; Buffer += (DWORD)((DWORD)pTarget ^ dwTmpRnd); break; case 4: case 5: case 6: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(((DWORD)pTarget << ((BYTE)dwTmpRnd & 31)) | ((DWORD)pTarget >> (32 - ((BYTE)dwTmpRnd & 31)))); Buffer += (BYTE)0xC1; //ror dword ptr [esp], Buffer += (BYTE)0x0C; Buffer += (BYTE)0x24; Buffer += (BYTE)dwTmpRnd; break; case 7: case 8: case 9: Buffer += (BYTE)0x68; //push Buffer += (DWORD)(pTarget - dwTmpRnd); Buffer += (BYTE)0x81; //add dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; Buffer += (DWORD)dwTmpRnd; break; } switch(m_ubDetourType){ case 1: case 4: case 7: Buffer += (BYTE)0xC3; //ret break; case 2: case 5: case 8: Buffer += (BYTE)0xC2; //retn Buffer += (WORD)0; break; case 3: case 6: case 9: Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xC4; Buffer += (BYTE)0x04; Buffer += (BYTE)0xFF; //jmp dword ptr [esp-4] Buffer += (BYTE)0x64; Buffer += (BYTE)0x24; Buffer += (BYTE)0xFC; break; } if(iFinalSize != -1){ if(iFinalSize < (int)Buffer.Size()) return false; while((int)Buffer.Size() < iFinalSize) Buffer += (BYTE)OP_NOP; } return true; } bool CDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- if(m_bPolymorphic) m_ubDetourType = (BYTE)(rand() % RAND_DETOUR_TYPES) + 1; else m_ubDetourType = 0; int iRawDetourSize = GetDetourSize(); if(iRawDetourSize == -1) return false; if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize){ if(!m_bPolymorphic) return false; for(m_ubDetourType = 1; m_ubDetourType <= RAND_DETOUR_TYPES; m_ubDetourType++){ iRawDetourSize = GetDetourSize(); if(iRawDetourSize <= m_iBytesToOverwrite) break; } if(m_ubDetourType > RAND_DETOUR_TYPES) return false; } //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect((void*)m_dwAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); if(!m_bNoRegs){ Buffer += (BYTE)0x89; //mov dword ptr, ecx Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; } Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0x83; //sub esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; int iCallOrgEndOffsetIndex = -1; int iCallOrgEndOffset = -1; if(m_bAutoReturn){ //Buffer += (BYTE)0xCC; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)1; Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bReturnToOriginal; Buffer += (BYTE)0; Buffer += (BYTE)0x74; //je iCallOrgEndOffsetIndex = Buffer + (BYTE)0; if(m_iArgsOverride <= 0){ Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; } Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pOrgGateBuf; if(m_iArgsOverride > 0){ iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pAutoReturnEndStack; iCallOrgEndOffset = Buffer.Peek() - iCallOrgEndOffsetIndex - 1; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateRealRet; } }else if(m_iArgsOverride > 0){ Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pGateStack; Buffer += (BYTE)0xFF; //push dword ptr Buffer += (BYTE)0x35; Buffer += (DWORD)&m_pGateRealRet; Buffer += (BYTE)0xC2; //retn Buffer += (WORD)(m_iArgsOverride * 4); }else{ Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pFuncToCall; } m_pGateBuf = Buffer.Copy(); if(m_bAutoReturn) *(BYTE*)&m_pGateBuf[iCallOrgEndOffsetIndex] = (BYTE)iCallOrgEndOffset; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pOrgReturnAddress; Buffer += (BYTE)0x89; //mov dword ptr, esp Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0x83; //add esp, 4 Buffer += (BYTE)0xEC; Buffer += (BYTE)0x04; Buffer += (BYTE)0xC7; //mov dword ptr [esp], Buffer += (BYTE)0x04; Buffer += (BYTE)0x24; int iOrgReturnAddressIndex = Buffer + (DWORD)0; if(!m_bNoRegs){ Buffer += (BYTE)0x80; //cmp byte ptr Buffer += (BYTE)0x3D; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; Buffer += (BYTE)0x0F; //cmove ecx, dword ptr Buffer += (BYTE)0x44; Buffer += (BYTE)0x0D; Buffer += (DWORD)&m_pClassInstance; Buffer += (BYTE)0xC6; //mov byte ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_bDontReplaceOrgClassInstance; Buffer += (BYTE)0x00; //Buffer += (BYTE)0x8B; //mov ecx, dword ptr //Buffer += (BYTE)0x0D; //Buffer += (DWORD)&m_pClassInstance; } //----- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect((void*)m_pAddr, m_iDetourSize, pOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; m_pOrgAfterDetour = pbSrc; //----- if(!(*pbLastOp == OP_BRK || *pbLastOp == OP_NOP)){ //align [end of function] Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgAfterDetour; } int iOrgReturnAddressOffset = Buffer.Peek(); Buffer += (BYTE)0x8B; //mov esp, dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgStack; Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pOrgReturnAddress; m_pOrgGateBuf = Buffer.Copy(); //----- *(DWORD*)&m_pOrgGateBuf[iOrgReturnAddressIndex] = (DWORD)&m_pOrgGateBuf[iOrgReturnAddressOffset]; BYTE* pbDst = &m_pOrgGateBuf[iOverwrittenOpsIndex]; pbSrc = (BYTE*)m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- if(!GenerateDetour(Buffer, m_pAddr, m_pGateBuf, m_iDetourSize)) return false; m_pDetourBuf = Buffer.Copy(); Buffer.Clear(); //----------------- Org = (CDetourOrg_Func)m_pOrgGateBuf; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; } int CSimpleDetour::g_iApplied = 0; int CSimpleDetour::g_iRemoved = 0; int CSimpleDetour::Applied(){ return g_iApplied; } int CSimpleDetour::Removed(){ return g_iRemoved; } CSimpleDetour::CSimpleDetour(){ m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; Deconstruct(); }; CSimpleDetour::~CSimpleDetour(){ Deconstruct(); }; void CSimpleDetour::Deconstruct(){ m_bReady = false; if(m_bApplied) Remove(); FreeBuffers(); m_iBytesToOverwrite = 0; m_pAddr = NULL; m_pFuncToCall = NULL; m_iDetourSize = 0; m_pRetAddress = 0; } void CSimpleDetour::FreeBuffers(){ m_bReady = false; if(m_pDetourBuf) delete[] m_pDetourBuf; if(m_pOrgBuf) delete[] m_pOrgBuf; if(m_pGateBuf) delete[] m_pGateBuf; m_pDetourBuf = NULL; m_pOrgBuf = NULL; m_pGateBuf = NULL; } bool CSimpleDetour::Detour(BYTE* pAddr, BYTE* pFuncToCall, bool bExecuteOverwrittenOps, int iBytesToOverwrite){ Deconstruct(); if(!pAddr || !pFuncToCall) return false; m_pAddr = pAddr; m_pFuncToCall = pFuncToCall; m_bExecuteOverwrittenOps = bExecuteOverwrittenOps; m_iBytesToOverwrite = iBytesToOverwrite; return Generate(); } bool CSimpleDetour::WriteToAddr(BYTE* pBuffer, int iSize){ if(!m_bReady) return false;; DWORD dwOldProt, dwDummy; if(!VirtualProtect(m_pAddr, iSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) return false; if(!memcpy(m_pAddr, pBuffer, iSize)) return false; FlushInstructionCache(GetCurrentProcess(), m_pAddr, iSize); VirtualProtect(m_pAddr, iSize, dwOldProt, &dwDummy); return true; } bool CSimpleDetour::Apply(){ if(!m_bReady || m_bApplied) return false;; if(!WriteToAddr(m_pDetourBuf, m_iDetourSize)) return false; m_bApplied = true; g_iApplied++; return true; } bool CSimpleDetour::Remove(){ if(!m_bApplied) return false; if(!WriteToAddr(m_pOrgBuf, m_iDetourSize)) return false; m_bApplied = false; g_iRemoved++; return true; } bool CSimpleDetour::IsReady(){ return m_bReady; } bool CSimpleDetour::IsApplied(){ return m_bApplied; } BYTE* CSimpleDetour::GetAddr(){ return m_pAddr; } BYTE* CSimpleDetour::GetFuncToCall(){ return m_pFuncToCall; } void CSimpleDetour::SetFuncToCall(BYTE* pFuncToCall){ m_pFuncToCall = pFuncToCall; } BYTE* CSimpleDetour::GetRetAddress(){ return m_pRetAddress; } bool CSimpleDetour::Generate(){ FreeBuffers(); CByteArray Buffer; //----------------- Buffer.Clear(); Buffer += (BYTE)0xE8; //call int iDetourOffsetIndex = Buffer + (DWORD)0; BYTE* pRawDetourBuf = Buffer.Copy(); int iRawDetourSize = Buffer.Peek(); if(m_iBytesToOverwrite > 0) if(m_iBytesToOverwrite < iRawDetourSize) return false; //----------------- //DWORD dwOldProt, dwDummy; //if(!VirtualProtect(m_pAddr, iRawDetourSize, PAGE_EXECUTE_READWRITE, &dwOldProt)) // return false; //----------------- Buffer.Clear(); Buffer += (BYTE)0x8F; //pop dword ptr Buffer += (BYTE)0x05; Buffer += (DWORD)&m_pRetAddress; Buffer += (BYTE)0xFF; //call dword ptr Buffer += (BYTE)0x15; Buffer += (DWORD)&m_pFuncToCall; //----------------- int iOverwrittenOpsIndex = Buffer.Peek(); int iOverwrittenOps = 0; int iOverwrittenBytes = 0; CDetourDis Dis(NULL, NULL); BYTE* pbSrc = m_pAddr; BYTE* pbLastOp = pbSrc; if(m_iBytesToOverwrite > 0){ iOverwrittenBytes = m_iBytesToOverwrite; pbSrc += iOverwrittenBytes; Buffer.Grow(iOverwrittenBytes); }else{ while(iOverwrittenBytes < iRawDetourSize){ pbLastOp = pbSrc; if(*pbSrc == OP_BRK) break; BYTE* pbNew = Dis.CopyInstruction(NULL, pbSrc); iOverwrittenOps++; int iDelta = (int)(pbNew - pbSrc); if((pbNew == NULL) || (iDelta == 0)){ //VirtualProtect(m_pAddr, m_iDetourSize, dwOldProt, &dwDummy); return false; } iOverwrittenBytes += iDelta; pbSrc += iDelta; Buffer.Grow(iDelta); pbSrc = pbNew; } } m_iDetourSize = iOverwrittenBytes; //----- Buffer += (BYTE)0xFF; //jmp dword ptr Buffer += (BYTE)0x25; Buffer += (DWORD)&m_pRetAddress; m_pGateBuf = Buffer.Copy(); //----------------- BYTE* pbDst = &m_pGateBuf[iOverwrittenOpsIndex]; pbSrc = m_pAddr; if(m_iBytesToOverwrite > 0){ memcpy(pbDst, pbSrc, iOverwrittenBytes); }else{ for(int iCurOp = 0; iCurOp < iOverwrittenOps; iCurOp++){ BYTE* pbNew = Dis.CopyInstruction(pbDst, pbSrc); pbDst += (pbNew - pbSrc); pbSrc = pbNew; } } //----------------- *(int*)&pRawDetourBuf[iDetourOffsetIndex] = m_pGateBuf - m_pAddr - 5; m_pDetourBuf = new BYTE[m_iDetourSize]; memset(m_pDetourBuf, OP_NOP, m_iDetourSize); memcpy(m_pDetourBuf, pRawDetourBuf, iRawDetourSize); delete[] pRawDetourBuf; pRawDetourBuf = NULL; //----------------- m_pOrgBuf = new BYTE[m_iDetourSize]; memcpy(m_pOrgBuf, m_pAddr, m_iDetourSize); //VirtualProtect((void*)m_dwAddr, m_iDetourSize, dwOldProt, &dwDummy); m_bReady = true; return true; }
Code:
////////////////////////////////////////////////////////////////////////////// // // Module: detours.lib // File: disasm.cpp // // Detours for binary functions. Version 1.5 (Build 46) // Includes support for all x86 chips prior to the Pentium III. // // Copyright 1999-2001, Microsoft Corporation // #define WIN32_LEAN_AND_MEAN #define WIN32_EXTRA_LEAN #include//#include //#include "detours.h" //#include "disasm.h" #include "CDetourDis.h" #undef ASSERT #define ASSERT(x) ////////////////////////////////////////////////////////////////////////////// // // Function: // DetourCopyInstruction(PBYTE pbDst, PBYTE pbSrc, PBYTE* ppbTarget) // Purpose: // Copy a single instruction from pbSrc to pbDst. // Arguments: // pbDst: // Destination address for the instruction. May be NULL in which // case DetourCopyInstruction is used to measure an instruction. // If not NULL then the source instruction is copied to the // destination instruction and any relative arguments are adjusted. // pbSrc: // Source address of the instruction. // ppbTarget: // Out parameter for any target instruction address pointed to by // the instruction. For example, a branch or a jump insruction has // a target, but a load or store instruction doesn't. A target is // another instruction that may be executed as a result of this // instruction. ppbTarget may be NULL. // plExtra: // Out parameter for the number of extra bytes needed by the // instruction to reach the target. For example, lExtra = 3 if the // instruction had an 8-bit relative offset, but needs a 32-bit // relative offset. // Returns: // Returns the address of the next instruction (following in the source) // instruction. By subtracting pbSrc from the return value, the caller // can determinte the size of the instruction copied. // Comments: // By following the pbTarget, the caller can follow alternate // instruction streams. However, it is not always possible to determine // the target based on static analysis. For example, the destination of // a jump relative to a register cannot be determined from just the // instruction stream. The output value, pbTarget, can have any of the // following outputs: // DETOUR_INSTRUCTION_TARGET_NONE: // The instruction has no targets. // DETOUR_INSTRUCTION_TARGET_DYNAMIC: // The instruction has a non-deterministic (dynamic) target. // (i.e. the jump is to an address held in a register.) // Address: The instruction has the specified target. // // When copying instructions, DetourCopyInstruction insures that any // targets remain constant. It does so by adjusting any IP relative // offsets. // PBYTE WINAPI DetourCopyInstructionEx(PBYTE pbDst, PBYTE pbSrc, PBYTE* ppbTarget, LONG* plExtra){ CDetourDis oDetourDisasm(ppbTarget, plExtra); return oDetourDisasm.CopyInstruction(pbDst, pbSrc); } PBYTE WINAPI DetourCopyInstruction(PBYTE pbDst, PBYTE pbSrc, PBYTE* ppbTarget){ CDetourDis oDetourDisasm(ppbTarget, NULL); return oDetourDisasm.CopyInstruction(pbDst, pbSrc); } /////////////////////////////////////////////////////////// Disassembler Code. CDetourDis::CDetourDis(PBYTE* ppbTarget, LONG* plExtra){ Set32BitOperand(); Set32BitAddress(); m_ppbTarget = ppbTarget ? ppbTarget : &m_pbScratchTarget; m_plExtra = plExtra ? plExtra : &m_lScratchExtra; *m_ppbTarget = DETOUR_INSTRUCTION_TARGET_NONE; *m_plExtra = 0; m_pbDstOverride = 0; m_bAdjustZero = FALSE; } VOID CDetourDis::Set16BitOperand(){ m_b16BitOperand = TRUE; } VOID CDetourDis::Set32BitOperand(){ m_b16BitOperand = FALSE; } VOID CDetourDis::Set16BitAddress(){ m_b16BitAddress = TRUE; } VOID CDetourDis::Set32BitAddress(){ m_b16BitAddress = FALSE; } PBYTE CDetourDis::CopyInstruction(PBYTE pbDst, PBYTE pbSrc){ // Configure scratch areas if real areas are not available. if(NULL == pbDst) pbDst = m_rbScratchDst; if(NULL == pbSrc){ // We can't copy a non-existent instruction. SetLastError(ERROR_INVALID_DATA); return NULL; } // Figure out how big the instruction is, do the appropriate copy, // and figure out what the target of the instruction is if any. REFCOPYENTRY pEntry = &s_rceCopyTable[pbSrc[0]]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } PBYTE CDetourDis::CopyInstructionEx(PBYTE pbDst, PBYTE pbSrc, PBYTE pbDstOverride){ m_pbDstOverride = pbDstOverride; PBYTE pbRet = CopyInstruction(pbDst, pbSrc); m_pbDstOverride = NULL; return pbRet; } PBYTE CDetourDis::CopyInstructionZero(PBYTE pbDst, PBYTE pbSrc){ m_bAdjustZero = TRUE; PBYTE pbRet = CopyInstructionEx(pbDst, pbSrc, NULL); m_bAdjustZero = FALSE; return pbRet; } BYTE CDetourDis::InstructionLen(PBYTE pbSrc){ PBYTE pbDst = m_rbScratchDst; if(NULL == pbSrc){ // We can't copy a non-existent instruction. SetLastError(ERROR_INVALID_DATA); return NULL; } // Figure out how big the instruction is, do the appropriate copy, // and figure out what the target of the instruction is if any. REFCOPYENTRY pEntry = &s_rceCopyTable[pbSrc[0]]; PBYTE pbEnd = (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); if(!pbEnd) return 0; return (BYTE)(pbEnd - pbSrc); } PBYTE CDetourDis::CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ LONG nBytesFixed = (pEntry->nFlagBits & ADDRESS) ? (m_b16BitAddress ? pEntry->nFixedSize16 : pEntry->nFixedSize) : (m_b16BitOperand ? pEntry->nFixedSize16 : pEntry->nFixedSize); LONG nBytes = nBytesFixed; BYTE bAddrOfs = 0; if(pEntry->nModOffset > 0){ BYTE bModRm = pbSrc[pEntry->nModOffset]; BYTE bFlags = s_rbModRm[bModRm]; if((bFlags & NOENLARGE) && ((bFlags & NOTSIB) == 4)) bAddrOfs = (BYTE)pEntry->nModOffset + 1; if(bFlags & SIB){ BYTE bSib = pbSrc[pEntry->nModOffset + 1]; if((bSib & 0x07) == 0x05){ if((bModRm & 0xc0) == 0x00) nBytes += 4; else if((bModRm & 0xc0) == 0x40) nBytes += 1; else if ((bModRm & 0xc0) == 0x80) nBytes += 4; } } nBytes += bFlags & NOTSIB; } CopyMemory(pbDst, pbSrc, nBytes); if(m_bAdjustZero && bAddrOfs) *(DWORD*)&pbDst[bAddrOfs] = 0; if(pEntry->nRelOffset) *m_ppbTarget = AdjustTarget(pbDst, pbSrc, nBytesFixed, pEntry->nRelOffset); if(pEntry->nFlagBits & NOENLARGE) *m_plExtra = -*m_plExtra; if(pEntry->nFlagBits & DYNAMIC) *m_ppbTarget = DETOUR_INSTRUCTION_TARGET_DYNAMIC; return pbSrc + nBytes; } PBYTE CDetourDis::CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ CopyBytes(pEntry, pbDst, pbSrc); pEntry = &s_rceCopyTable[pbSrc[1]]; return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1); } PBYTE CDetourDis::AdjustTarget(PBYTE pbDst, PBYTE pbSrc, LONG cbOp, LONG cbTargetOffset){ LONG cbTargetSize = cbOp - cbTargetOffset; PBYTE pbTarget = NULL; PVOID pvTargetAddr = &pbDst[cbTargetOffset]; LONG nOldOffset = 0; switch(cbTargetSize){ case 1: nOldOffset = (LONG)*(PCHAR&)pvTargetAddr; *m_plExtra = 3; break; case 2: nOldOffset = (LONG)*(PSHORT&)pvTargetAddr; *m_plExtra = 2; break; case 4: nOldOffset = (LONG)*(PLONG&)pvTargetAddr; *m_plExtra = 0; break; default: ASSERT(!"cbTargetSize is invalid."); break; } pbTarget = pbSrc + cbOp + nOldOffset; LONG nNewOffset = nOldOffset - (((m_pbDstOverride != NULL) ? m_pbDstOverride : pbDst) - pbSrc); switch (cbTargetSize) { case 1: *(PCHAR&)pvTargetAddr = (CHAR)nNewOffset; break; case 2: *(PSHORT&)pvTargetAddr = (SHORT)nNewOffset; break; case 4: *(PLONG&)pvTargetAddr = (LONG)nNewOffset; break; } ASSERT(pbDst + cbOp + nNewOffset == pbTarget); return pbTarget; } PBYTE CDetourDis::Invalid(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ (void)pbDst; (void)pEntry; ASSERT(!"Invalid Instruction"); return pbSrc + 1; } ////////////////////////////////////////////////////// Individual Bytes Codes. PBYTE CDetourDis::Copy0F(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ CopyBytes(pEntry, pbDst, pbSrc); pEntry = &s_rceCopyTable0F[pbSrc[1]]; return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1); } PBYTE CDetourDis::Copy66(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ // Operand-size override prefix Set16BitOperand(); return CopyBytesPrefix(pEntry, pbDst, pbSrc); } PBYTE CDetourDis::Copy67(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ // Address size override prefix Set16BitAddress(); return CopyBytesPrefix(pEntry, pbDst, pbSrc); } PBYTE CDetourDis::CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ (void)pEntry; // TEST BYTE /0 if(0x00 == (0x38 & pbSrc[1])){ // reg(bits 543) of ModR/M == 0 const COPYENTRY ce = { 0xf6, ENTRY_CopyBytes2Mod1 }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } // DIV /6 // IDIV /7 // IMUL /5 // MUL /4 // NEG /3 // NOT /2 const COPYENTRY ce = { 0xf6, ENTRY_CopyBytes2Mod }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } PBYTE CDetourDis::CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ (void)pEntry; // TEST WORD /0 if(0x00 == (0x38 & pbSrc[1])){ // reg(bits 543) of ModR/M == 0 const COPYENTRY ce = {0xf7, ENTRY_CopyBytes2ModOperand}; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } // DIV /6 // IDIV /7 // IMUL /5 // MUL /4 // NEG /3 // NOT /2 const COPYENTRY ce = { 0xf7, ENTRY_CopyBytes2Mod }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc){ // CALL /2 // CALL /3 // INC /0 // JMP /4 // JMP /5 // PUSH /6 (void)pEntry; if(0x15 == pbSrc[1] || 0x25 == pbSrc[1]){ // CALL [], JMP [] PBYTE* ppbTarget = *(PBYTE**)&pbSrc[2]; *m_ppbTarget = *ppbTarget; }else if(0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of ModR/M == 010 0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of ModR/M == 011 0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of ModR/M == 100 0x28 == (0x38 & pbSrc[1]) // JMP /5 --> reg(bits 543) of ModR/M == 101 ){ *m_ppbTarget = DETOUR_INSTRUCTION_TARGET_DYNAMIC; } const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod }; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } ///////////////////////////////////////////////////////// Disassembler Tables. const BYTE CDetourDis::s_rbModRm[256] = { 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 0x 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 1x 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 2x 0,0,0,0, SIB|1,4,0,0, 0,0,0,0, SIB|1,4,0,0, // 3x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 4x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 5x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 6x 1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 7x 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // 8x 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // 9x 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // Ax 4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // Bx 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Cx 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Dx 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Ex 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 // Fx }; const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable[257] = { { 0x00, ENTRY_CopyBytes2Mod }, // ADD /r { 0x01, ENTRY_CopyBytes2Mod }, // ADD /r { 0x02, ENTRY_CopyBytes2Mod }, // ADD /r { 0x03, ENTRY_CopyBytes2Mod }, // ADD /r { 0x04, ENTRY_CopyBytes2 }, // ADD ib { 0x05, ENTRY_CopyBytes3Or5 }, // ADD iw { 0x06, ENTRY_CopyBytes1 }, // PUSH { 0x07, ENTRY_CopyBytes1 }, // POP { 0x08, ENTRY_CopyBytes2Mod }, // OR /r { 0x09, ENTRY_CopyBytes2Mod }, // OR /r { 0x0A, ENTRY_CopyBytes2Mod }, // OR /r { 0x0B, ENTRY_CopyBytes2Mod }, // OR /r { 0x0C, ENTRY_CopyBytes2 }, // OR ib { 0x0D, ENTRY_CopyBytes3Or5 }, // OR iw { 0x0E, ENTRY_CopyBytes1 }, // PUSH { 0x0F, ENTRY_Copy0F }, // Extension Ops { 0x10, ENTRY_CopyBytes2Mod }, // ADC /r { 0x11, ENTRY_CopyBytes2Mod }, // ADC /r { 0x12, ENTRY_CopyBytes2Mod }, // ADC /r { 0x13, ENTRY_CopyBytes2Mod }, // ADC /r { 0x14, ENTRY_CopyBytes2 }, // ADC ib { 0x15, ENTRY_CopyBytes3Or5 }, // ADC id { 0x16, ENTRY_CopyBytes1 }, // PUSH { 0x17, ENTRY_CopyBytes1 }, // POP { 0x18, ENTRY_CopyBytes2Mod }, // SBB /r { 0x19, ENTRY_CopyBytes2Mod }, // SBB /r { 0x1A, ENTRY_CopyBytes2Mod }, // SBB /r { 0x1B, ENTRY_CopyBytes2Mod }, // SBB /r { 0x1C, ENTRY_CopyBytes2 }, // SBB ib { 0x1D, ENTRY_CopyBytes3Or5 }, // SBB id { 0x1E, ENTRY_CopyBytes1 }, // PUSH { 0x1F, ENTRY_CopyBytes1 }, // POP { 0x20, ENTRY_CopyBytes2Mod }, // AND /r { 0x21, ENTRY_CopyBytes2Mod }, // AND /r { 0x22, ENTRY_CopyBytes2Mod }, // AND /r { 0x23, ENTRY_CopyBytes2Mod }, // AND /r { 0x24, ENTRY_CopyBytes2 }, // AND ib { 0x25, ENTRY_CopyBytes3Or5 }, // AND id { 0x26, ENTRY_CopyBytesPrefix }, // ES prefix { 0x27, ENTRY_CopyBytes1 }, // DAA { 0x28, ENTRY_CopyBytes2Mod }, // SUB /r { 0x29, ENTRY_CopyBytes2Mod }, // SUB /r { 0x2A, ENTRY_CopyBytes2Mod }, // SUB /r { 0x2B, ENTRY_CopyBytes2Mod }, // SUB /r { 0x2C, ENTRY_CopyBytes2 }, // SUB ib { 0x2D, ENTRY_CopyBytes3Or5 }, // SUB id { 0x2E, ENTRY_CopyBytesPrefix }, // CS prefix { 0x2F, ENTRY_CopyBytes1 }, // DAS { 0x30, ENTRY_CopyBytes2Mod }, // XOR /r { 0x31, ENTRY_CopyBytes2Mod }, // XOR /r { 0x32, ENTRY_CopyBytes2Mod }, // XOR /r { 0x33, ENTRY_CopyBytes2Mod }, // XOR /r { 0x34, ENTRY_CopyBytes2 }, // XOR ib { 0x35, ENTRY_CopyBytes3Or5 }, // XOR id { 0x36, ENTRY_CopyBytesPrefix }, // SS prefix { 0x37, ENTRY_CopyBytes1 }, // AAA { 0x38, ENTRY_CopyBytes2Mod }, // CMP /r { 0x39, ENTRY_CopyBytes2Mod }, // CMP /r { 0x3A, ENTRY_CopyBytes2Mod }, // CMP /r { 0x3B, ENTRY_CopyBytes2Mod }, // CMP /r { 0x3C, ENTRY_CopyBytes2 }, // CMP ib { 0x3D, ENTRY_CopyBytes3Or5 }, // CMP id { 0x3E, ENTRY_CopyBytesPrefix }, // DS prefix { 0x3F, ENTRY_CopyBytes1 }, // AAS { 0x40, ENTRY_CopyBytes1 }, // INC { 0x41, ENTRY_CopyBytes1 }, // INC { 0x42, ENTRY_CopyBytes1 }, // INC { 0x43, ENTRY_CopyBytes1 }, // INC { 0x44, ENTRY_CopyBytes1 }, // INC { 0x45, ENTRY_CopyBytes1 }, // INC { 0x46, ENTRY_CopyBytes1 }, // INC { 0x47, ENTRY_CopyBytes1 }, // INC { 0x48, ENTRY_CopyBytes1 }, // DEC { 0x49, ENTRY_CopyBytes1 }, // DEC { 0x4A, ENTRY_CopyBytes1 }, // DEC { 0x4B, ENTRY_CopyBytes1 }, // DEC { 0x4C, ENTRY_CopyBytes1 }, // DEC { 0x4D, ENTRY_CopyBytes1 }, // DEC { 0x4E, ENTRY_CopyBytes1 }, // DEC { 0x4F, ENTRY_CopyBytes1 }, // DEC { 0x50, ENTRY_CopyBytes1 }, // PUSH { 0x51, ENTRY_CopyBytes1 }, // PUSH { 0x52, ENTRY_CopyBytes1 }, // PUSH { 0x53, ENTRY_CopyBytes1 }, // PUSH { 0x54, ENTRY_CopyBytes1 }, // PUSH { 0x55, ENTRY_CopyBytes1 }, // PUSH { 0x56, ENTRY_CopyBytes1 }, // PUSH { 0x57, ENTRY_CopyBytes1 }, // PUSH { 0x58, ENTRY_CopyBytes1 }, // POP { 0x59, ENTRY_CopyBytes1 }, // POP { 0x5A, ENTRY_CopyBytes1 }, // POP { 0x5B, ENTRY_CopyBytes1 }, // POP { 0x5C, ENTRY_CopyBytes1 }, // POP { 0x5D, ENTRY_CopyBytes1 }, // POP { 0x5E, ENTRY_CopyBytes1 }, // POP { 0x5F, ENTRY_CopyBytes1 }, // POP { 0x60, ENTRY_CopyBytes1 }, // PUSHAD { 0x61, ENTRY_CopyBytes1 }, // POPAD { 0x62, ENTRY_CopyBytes2Mod }, // BOUND /r { 0x63, ENTRY_CopyBytes2Mod }, // ARPL /r { 0x64, ENTRY_CopyBytesPrefix }, // FS prefix { 0x65, ENTRY_CopyBytesPrefix }, // GS prefix { 0x66, ENTRY_Copy66 }, // Operand Prefix { 0x67, ENTRY_Copy67 }, // Address Prefix { 0x68, ENTRY_CopyBytes3Or5 }, // PUSH { 0x69, ENTRY_CopyBytes2ModOperand }, // { 0x6A, ENTRY_CopyBytes2 }, // PUSH { 0x6B, ENTRY_CopyBytes2Mod1 }, // IMUL /r ib { 0x6C, ENTRY_CopyBytes1 }, // INS { 0x6D, ENTRY_CopyBytes1 }, // INS { 0x6E, ENTRY_CopyBytes1 }, // OUTS/OUTSB { 0x6F, ENTRY_CopyBytes1 }, // OUTS/OUTSW { 0x70, ENTRY_CopyBytes2Jump }, // JO { 0x71, ENTRY_CopyBytes2Jump }, // JNO { 0x72, ENTRY_CopyBytes2Jump }, // JB/JC/JNAE { 0x73, ENTRY_CopyBytes2Jump }, // JAE/JNB/JNC { 0x74, ENTRY_CopyBytes2Jump }, // JE/JZ { 0x75, ENTRY_CopyBytes2Jump }, // JNE/JNZ { 0x76, ENTRY_CopyBytes2Jump }, // JBE/JNA { 0x77, ENTRY_CopyBytes2Jump }, // JA/JNBE { 0x78, ENTRY_CopyBytes2Jump }, // JS { 0x79, ENTRY_CopyBytes2Jump }, // JNS { 0x7A, ENTRY_CopyBytes2Jump }, // JP/JPE { 0x7B, ENTRY_CopyBytes2Jump }, // JNP/JPO { 0x7C, ENTRY_CopyBytes2Jump }, // JL/JNGE { 0x7D, ENTRY_CopyBytes2Jump }, // JGE/JNL { 0x7E, ENTRY_CopyBytes2Jump }, // JLE/JNG { 0x7F, ENTRY_CopyBytes2Jump }, // JG/JNLE { 0x80, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.s { 0x81, ENTRY_CopyBytes2ModOperand }, // { 0x82, ENTRY_CopyBytes2 }, // MOV al,x { 0x83, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc. { 0x84, ENTRY_CopyBytes2Mod }, // TEST /r { 0x85, ENTRY_CopyBytes2Mod }, // TEST /r { 0x86, ENTRY_CopyBytes2Mod }, // XCHG /r @todo { 0x87, ENTRY_CopyBytes2Mod }, // XCHG /r @todo { 0x88, ENTRY_CopyBytes2Mod }, // MOV /r { 0x89, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8A, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8B, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8C, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8D, ENTRY_CopyBytes2Mod }, // LEA /r { 0x8E, ENTRY_CopyBytes2Mod }, // MOV /r { 0x8F, ENTRY_CopyBytes2Mod }, // POP /0 { 0x90, ENTRY_CopyBytes1 }, // NOP { 0x91, ENTRY_CopyBytes1 }, // XCHG { 0x92, ENTRY_CopyBytes1 }, // XCHG { 0x93, ENTRY_CopyBytes1 }, // XCHG { 0x94, ENTRY_CopyBytes1 }, // XCHG { 0x95, ENTRY_CopyBytes1 }, // XCHG { 0x96, ENTRY_CopyBytes1 }, // XCHG { 0x97, ENTRY_CopyBytes1 }, // XCHG { 0x98, ENTRY_CopyBytes1 }, // CWDE { 0x99, ENTRY_CopyBytes1 }, // CDQ { 0x9A, ENTRY_CopyBytes5Or7Dynamic }, // CALL cp { 0x9B, ENTRY_CopyBytes1 }, // WAIT/FWAIT { 0x9C, ENTRY_CopyBytes1 }, // PUSHFD { 0x9D, ENTRY_CopyBytes1 }, // POPFD { 0x9E, ENTRY_CopyBytes1 }, // SAHF { 0x9F, ENTRY_CopyBytes1 }, // LAHF { 0xA0, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA1, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA2, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA3, ENTRY_CopyBytes3Or5Address }, // MOV { 0xA4, ENTRY_CopyBytes1 }, // MOVS { 0xA5, ENTRY_CopyBytes1 }, // MOVS/MOVSD { 0xA6, ENTRY_CopyBytes1 }, // CMPS/CMPSB { 0xA7, ENTRY_CopyBytes1 }, // CMPS/CMPSW { 0xA8, ENTRY_CopyBytes2 }, // TEST { 0xA9, ENTRY_CopyBytes3Or5 }, // TEST { 0xAA, ENTRY_CopyBytes1 }, // STOS/STOSB { 0xAB, ENTRY_CopyBytes1 }, // STOS/STOSW { 0xAC, ENTRY_CopyBytes1 }, // LODS/LODSB { 0xAD, ENTRY_CopyBytes1 }, // LODS/LODSW { 0xAE, ENTRY_CopyBytes1 }, // SCAS/SCASB { 0xAF, ENTRY_CopyBytes1 }, // SCAS/SCASD { 0xB0, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB1, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB2, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB3, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB4, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB5, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB6, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB7, ENTRY_CopyBytes2 }, // MOV B0+rb { 0xB8, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xB9, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBA, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBB, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBC, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBD, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBE, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xBF, ENTRY_CopyBytes3Or5 }, // MOV B8+rb { 0xC0, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc. { 0xC1, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc. { 0xC2, ENTRY_CopyBytes3 }, // RET { 0xC3, ENTRY_CopyBytes1 }, // RET { 0xC4, ENTRY_CopyBytes2Mod }, // LES { 0xC5, ENTRY_CopyBytes2Mod }, // LDS { 0xC6, ENTRY_CopyBytes2Mod1 }, // MOV { 0xC7, ENTRY_CopyBytes2ModOperand }, // MOV { 0xC8, ENTRY_CopyBytes4 }, // ENTER { 0xC9, ENTRY_CopyBytes1 }, // LEAVE { 0xCA, ENTRY_CopyBytes3Dynamic }, // RET { 0xCB, ENTRY_CopyBytes1Dynamic }, // RET { 0xCC, ENTRY_CopyBytes1Dynamic }, // INT 3 { 0xCD, ENTRY_CopyBytes2Dynamic }, // INT ib { 0xCE, ENTRY_CopyBytes1Dynamic }, // INTO { 0xCF, ENTRY_CopyBytes1Dynamic }, // IRET { 0xD0, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD1, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD2, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD3, ENTRY_CopyBytes2Mod }, // RCL/2, etc. { 0xD4, ENTRY_CopyBytes2 }, // AAM { 0xD5, ENTRY_CopyBytes2 }, // AAD { 0xD6, ENTRY_Invalid }, // { 0xD7, ENTRY_CopyBytes1 }, // XLAT/XLATB { 0xD8, ENTRY_CopyBytes2Mod }, // FADD, etc. { 0xD9, ENTRY_CopyBytes2Mod }, // F2XM1, etc. { 0xDA, ENTRY_CopyBytes2Mod }, // FLADD, etc. { 0xDB, ENTRY_CopyBytes2Mod }, // FCLEX, etc. { 0xDC, ENTRY_CopyBytes2Mod }, // FADD/0, etc. { 0xDD, ENTRY_CopyBytes2Mod }, // FFREE, etc. { 0xDE, ENTRY_CopyBytes2Mod }, // FADDP, etc. { 0xDF, ENTRY_CopyBytes2Mod }, // FBLD/4, etc. { 0xE0, ENTRY_CopyBytes2CantJump }, // LOOPNE cb { 0xE1, ENTRY_CopyBytes2CantJump }, // LOOPE cb { 0xE2, ENTRY_CopyBytes2CantJump }, // LOOP cb { 0xE3, ENTRY_CopyBytes2Jump }, // JCXZ/JECXZ { 0xE4, ENTRY_CopyBytes2 }, // IN ib { 0xE5, ENTRY_CopyBytes2 }, // IN id { 0xE6, ENTRY_CopyBytes2 }, // OUT ib { 0xE7, ENTRY_CopyBytes2 }, // OUT ib { 0xE8, ENTRY_CopyBytes3Or5Target }, // CALL cd { 0xE9, ENTRY_CopyBytes3Or5Target }, // JMP cd { 0xEA, ENTRY_CopyBytes5Or7Dynamic }, // JMP cp { 0xEB, ENTRY_CopyBytes2Jump }, // JMP cb { 0xEC, ENTRY_CopyBytes1 }, // IN ib { 0xED, ENTRY_CopyBytes1 }, // IN id { 0xEE, ENTRY_CopyBytes1 }, // OUT { 0xEF, ENTRY_CopyBytes1 }, // OUT { 0xF0, ENTRY_CopyBytesPrefix }, // LOCK prefix { 0xF1, ENTRY_Invalid }, // { 0xF2, ENTRY_CopyBytesPrefix }, // REPNE prefix { 0xF3, ENTRY_CopyBytesPrefix }, // REPE prefix { 0xF4, ENTRY_CopyBytes1 }, // HLT { 0xF5, ENTRY_CopyBytes1 }, // CMC { 0xF6, ENTRY_CopyF6 }, // TEST/0, DIV/6 { 0xF7, ENTRY_CopyF7 }, // TEST/0, DIV/6 { 0xF8, ENTRY_CopyBytes1 }, // CLC { 0xF9, ENTRY_CopyBytes1 }, // STC { 0xFA, ENTRY_CopyBytes1 }, // CLI { 0xFB, ENTRY_CopyBytes1 }, // STI { 0xFC, ENTRY_CopyBytes1 }, // CLD { 0xFD, ENTRY_CopyBytes1 }, // STD { 0xFE, ENTRY_CopyBytes2Mod }, // DEC/1,INC/0 { 0xFF, ENTRY_CopyFF }, // CALL/2 { 0, ENTRY_End }, }; const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable0F[257] = { { 0x00, ENTRY_CopyBytes2Mod }, // LLDT/2, etc. { 0x01, ENTRY_CopyBytes2Mod }, // INVLPG/7, etc. { 0x02, ENTRY_CopyBytes2Mod }, // LAR/r { 0x03, ENTRY_CopyBytes2Mod }, // LSL/r { 0x04, ENTRY_Invalid }, // _04 { 0x05, ENTRY_Invalid }, // _05 { 0x06, ENTRY_CopyBytes2 }, // CLTS { 0x07, ENTRY_Invalid }, // _07 { 0x08, ENTRY_CopyBytes2 }, // INVD { 0x09, ENTRY_CopyBytes2 }, // WBINVD { 0x0A, ENTRY_Invalid }, // _0A { 0x0B, ENTRY_CopyBytes2 }, // UD2 { 0x0C, ENTRY_Invalid }, // _0C { 0x0D, ENTRY_Invalid }, // _0D { 0x0E, ENTRY_Invalid }, // _0E { 0x0F, ENTRY_Invalid }, // _0F { 0x10, ENTRY_Invalid }, // _10 { 0x11, ENTRY_Invalid }, // _11 { 0x12, ENTRY_Invalid }, // _12 { 0x13, ENTRY_Invalid }, // _13 { 0x14, ENTRY_Invalid }, // _14 { 0x15, ENTRY_Invalid }, // _15 { 0x16, ENTRY_Invalid }, // _16 { 0x17, ENTRY_Invalid }, // _17 { 0x18, ENTRY_Invalid }, // _18 { 0x19, ENTRY_Invalid }, // _19 { 0x1A, ENTRY_Invalid }, // _1A { 0x1B, ENTRY_Invalid }, // _1B { 0x1C, ENTRY_Invalid }, // _1C { 0x1D, ENTRY_Invalid }, // _1D { 0x1E, ENTRY_Invalid }, // _1E { 0x1F, ENTRY_Invalid }, // _1F { 0x20, ENTRY_CopyBytes2Mod }, // MOV/r { 0x21, ENTRY_CopyBytes2Mod }, // MOV/r { 0x22, ENTRY_CopyBytes2Mod }, // MOV/r { 0x23, ENTRY_CopyBytes2Mod }, // MOV/r { 0x24, ENTRY_Invalid }, // _24 { 0x25, ENTRY_Invalid }, // _25 { 0x26, ENTRY_Invalid }, // _26 { 0x27, ENTRY_Invalid }, // _27 { 0x28, ENTRY_Invalid }, // _28 { 0x29, ENTRY_Invalid }, // _29 { 0x2A, ENTRY_Invalid }, // _2A { 0x2B, ENTRY_Invalid }, // _2B { 0x2C, ENTRY_Invalid }, // _2C { 0x2D, ENTRY_Invalid }, // _2D { 0x2E, ENTRY_Invalid }, // _2E { 0x2F, ENTRY_Invalid }, // _2F { 0x30, ENTRY_CopyBytes2 }, // WRMSR { 0x31, ENTRY_CopyBytes2 }, // RDTSC { 0x32, ENTRY_CopyBytes2 }, // RDMSR { 0x33, ENTRY_CopyBytes2 }, // RDPMC { 0x34, ENTRY_CopyBytes2 }, // SYSENTER { 0x35, ENTRY_CopyBytes2 }, // SYSEXIT { 0x36, ENTRY_Invalid }, // _36 { 0x37, ENTRY_Invalid }, // _37 { 0x38, ENTRY_Invalid }, // _38 { 0x39, ENTRY_Invalid }, // _39 { 0x3A, ENTRY_Invalid }, // _3A { 0x3B, ENTRY_Invalid }, // _3B { 0x3C, ENTRY_Invalid }, // _3C { 0x3D, ENTRY_Invalid }, // _3D { 0x3E, ENTRY_Invalid }, // _3E { 0x3F, ENTRY_Invalid }, // _3F { 0x40, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40) { 0x41, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41) { 0x42, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVNE (0F 42) { 0x43, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB (0F 43) { 0x44, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44) { 0x45, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45) { 0x46, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46) { 0x47, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47) { 0x48, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48) { 0x49, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49) { 0x4A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A) { 0x4B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B) { 0x4C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C) { 0x4D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D) { 0x4E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E) { 0x4F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F) { 0x50, ENTRY_Invalid }, // _50 { 0x51, ENTRY_Invalid }, // _51 { 0x52, ENTRY_Invalid }, // _52 { 0x53, ENTRY_Invalid }, // _53 { 0x54, ENTRY_Invalid }, // _54 { 0x55, ENTRY_Invalid }, // _55 { 0x56, ENTRY_Invalid }, // _56 { 0x57, ENTRY_Invalid }, // _57 { 0x58, ENTRY_Invalid }, // _58 { 0x59, ENTRY_Invalid }, // _59 { 0x5A, ENTRY_Invalid }, // _5A { 0x5B, ENTRY_Invalid }, // _5B { 0x5C, ENTRY_Invalid }, // _5C { 0x5D, ENTRY_Invalid }, // _5D { 0x5E, ENTRY_Invalid }, // _5E { 0x5F, ENTRY_Invalid }, // _5F { 0x60, ENTRY_CopyBytes2Mod }, // PUNPCKLBW/r { 0x61, ENTRY_Invalid }, // _61 { 0x62, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r { 0x63, ENTRY_CopyBytes2Mod }, // PACKSSWB/r { 0x64, ENTRY_CopyBytes2Mod }, // PCMPGTB/r { 0x65, ENTRY_CopyBytes2Mod }, // PCMPGTW/r { 0x66, ENTRY_CopyBytes2Mod }, // PCMPGTD/r { 0x67, ENTRY_CopyBytes2Mod }, // PACKUSWB/r { 0x68, ENTRY_CopyBytes2Mod }, // PUNPCKHBW/r { 0x69, ENTRY_CopyBytes2Mod }, // PUNPCKHWD/r { 0x6A, ENTRY_CopyBytes2Mod }, // PUNPCKHDQ/r { 0x6B, ENTRY_CopyBytes2Mod }, // PACKSSDW/r { 0x6C, ENTRY_Invalid }, // _6C { 0x6D, ENTRY_Invalid }, // _6D { 0x6E, ENTRY_CopyBytes2Mod }, // MOVD/r { 0x6F, ENTRY_CopyBytes2Mod }, // MOV/r { 0x70, ENTRY_Invalid }, // _70 { 0x71, ENTRY_CopyBytes2Mod1 }, // PSLLW/6 ib,PSRAW/4 ib,PSRLW/2 ib { 0x72, ENTRY_CopyBytes2Mod1 }, // PSLLD/6 ib,PSRAD/4 ib,PSRLD/2 ib { 0x73, ENTRY_CopyBytes2Mod1 }, // PSLLQ/6 ib,PSRLQ/2 ib { 0x74, ENTRY_CopyBytes2Mod }, // PCMPEQB/r { 0x75, ENTRY_CopyBytes2Mod }, // PCMPEQW/r { 0x76, ENTRY_CopyBytes2Mod }, // PCMPEQD/r { 0x77, ENTRY_CopyBytes2 }, // EMMS { 0x78, ENTRY_Invalid }, // _78 { 0x79, ENTRY_Invalid }, // _79 { 0x7A, ENTRY_Invalid }, // _7A { 0x7B, ENTRY_Invalid }, // _7B { 0x7C, ENTRY_Invalid }, // _7C { 0x7D, ENTRY_Invalid }, // _7D { 0x7E, ENTRY_CopyBytes2Mod }, // MOVD/r { 0x7F, ENTRY_CopyBytes2Mod }, // MOV/r { 0x80, ENTRY_CopyBytes3Or5Target }, // JO { 0x81, ENTRY_CopyBytes3Or5Target }, // JNO { 0x82, ENTRY_CopyBytes3Or5Target }, // JB,JC,JNAE { 0x83, ENTRY_CopyBytes3Or5Target }, // JAE,JNB,JNC { 0x84, ENTRY_CopyBytes3Or5Target }, // JE,JZ,JZ { 0x85, ENTRY_CopyBytes3Or5Target }, // JNE,JNZ { 0x86, ENTRY_CopyBytes3Or5Target }, // JBE,JNA { 0x87, ENTRY_CopyBytes3Or5Target }, // JA,JNBE { 0x88, ENTRY_CopyBytes3Or5Target }, // JS { 0x89, ENTRY_CopyBytes3Or5Target }, // JNS { 0x8A, ENTRY_CopyBytes3Or5Target }, // JP,JPE { 0x8B, ENTRY_CopyBytes3Or5Target }, // JNP,JPO { 0x8C, ENTRY_CopyBytes3Or5Target }, // JL,NGE { 0x8D, ENTRY_CopyBytes3Or5Target }, // JGE,JNL { 0x8E, ENTRY_CopyBytes3Or5Target }, // JLE,JNG { 0x8F, ENTRY_CopyBytes3Or5Target }, // JG,JNLE { 0x90, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40) { 0x91, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41) { 0x92, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVC & CMOVNAE (0F 42) { 0x93, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB & CMOVNC (0F 43) { 0x94, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44) { 0x95, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45) { 0x96, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46) { 0x97, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47) { 0x98, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48) { 0x99, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49) { 0x9A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A) { 0x9B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B) { 0x9C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C) { 0x9D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D) { 0x9E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E) { 0x9F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F) { 0xA0, ENTRY_CopyBytes2 }, // PUSH { 0xA1, ENTRY_CopyBytes2 }, // POP { 0xA2, ENTRY_CopyBytes2 }, // CPUID { 0xA3, ENTRY_CopyBytes2Mod }, // BT (0F A3) { 0xA4, ENTRY_CopyBytes2Mod1 }, // SHLD { 0xA5, ENTRY_CopyBytes2Mod }, // SHLD { 0xA6, ENTRY_Invalid }, // _A6 { 0xA7, ENTRY_Invalid }, // _A7 { 0xA8, ENTRY_CopyBytes2 }, // PUSH { 0xA9, ENTRY_CopyBytes2 }, // POP { 0xAA, ENTRY_CopyBytes2 }, // RSM { 0xAB, ENTRY_CopyBytes2Mod }, // BTS (0F AB) { 0xAC, ENTRY_CopyBytes2Mod1 }, // SHRD { 0xAD, ENTRY_CopyBytes2Mod }, // SHRD { 0xAE, ENTRY_CopyBytes2Mod }, // FXRSTOR/1,FXSAVE/0 { 0xAF, ENTRY_CopyBytes2Mod }, // IMUL (0F AF) { 0xB0, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B0) { 0xB1, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B1) { 0xB2, ENTRY_CopyBytes2Mod }, // LSS/r { 0xB3, ENTRY_CopyBytes2Mod }, // BTR (0F B3) { 0xB4, ENTRY_CopyBytes2Mod }, // LFS/r { 0xB5, ENTRY_CopyBytes2Mod }, // LGS/r { 0xB6, ENTRY_CopyBytes2Mod }, // MOVZX/r { 0xB7, ENTRY_CopyBytes2Mod }, // MOVZX/r { 0xB8, ENTRY_Invalid }, // _B8 { 0xB9, ENTRY_Invalid }, // _B9 { 0xBA, ENTRY_CopyBytes2Mod1 }, // BT & BTC & BTR & BTS (0F BA) { 0xBB, ENTRY_CopyBytes2Mod }, // BTC (0F BB) { 0xBC, ENTRY_CopyBytes2Mod }, // BSF (0F BC) { 0xBD, ENTRY_CopyBytes2Mod }, // BSR (0F BD) { 0xBE, ENTRY_CopyBytes2Mod }, // MOVSX/r { 0xBF, ENTRY_CopyBytes2Mod }, // MOVSX/r { 0xC0, ENTRY_CopyBytes2Mod }, // XADD/r { 0xC1, ENTRY_CopyBytes2Mod }, // XADD/r { 0xC2, ENTRY_Invalid }, // _C2 { 0xC3, ENTRY_Invalid }, // _C3 { 0xC4, ENTRY_Invalid }, // _C4 { 0xC5, ENTRY_Invalid }, // _C5 { 0xC6, ENTRY_Invalid }, // _C6 { 0xC7, ENTRY_CopyBytes2Mod }, // CMPXCHG8B (0F C7) { 0xC8, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xC9, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCA, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCB, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCC, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCD, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCE, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xCF, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd { 0xD0, ENTRY_Invalid }, // _D0 { 0xD1, ENTRY_CopyBytes2Mod }, // PSRLW/r { 0xD2, ENTRY_CopyBytes2Mod }, // PSRLD/r { 0xD3, ENTRY_CopyBytes2Mod }, // PSRLQ/r { 0xD4, ENTRY_Invalid }, // _D4 { 0xD5, ENTRY_CopyBytes2Mod }, // PMULLW/r { 0xD6, ENTRY_Invalid }, // _D6 { 0xD7, ENTRY_Invalid }, // _D7 { 0xD8, ENTRY_CopyBytes2Mod }, // PSUBUSB/r { 0xD9, ENTRY_CopyBytes2Mod }, // PSUBUSW/r { 0xDA, ENTRY_Invalid }, // _DA { 0xDB, ENTRY_CopyBytes2Mod }, // PAND/r { 0xDC, ENTRY_CopyBytes2Mod }, // PADDUSB/r { 0xDD, ENTRY_CopyBytes2Mod }, // PADDUSW/r { 0xDE, ENTRY_Invalid }, // _DE { 0xDF, ENTRY_CopyBytes2Mod }, // PANDN/r { 0xE0, ENTRY_Invalid }, // _E0 { 0xE1, ENTRY_CopyBytes2Mod }, // PSRAW/r { 0xE2, ENTRY_CopyBytes2Mod }, // PSRAD/r { 0xE3, ENTRY_Invalid }, // _E3 { 0xE4, ENTRY_Invalid }, // _E4 { 0xE5, ENTRY_CopyBytes2Mod }, // PMULHW/r { 0xE6, ENTRY_Invalid }, // _E6 { 0xE7, ENTRY_Invalid }, // _E7 { 0xE8, ENTRY_CopyBytes2Mod }, // PSUBB/r { 0xE9, ENTRY_CopyBytes2Mod }, // PSUBW/r { 0xEA, ENTRY_Invalid }, // _EA { 0xEB, ENTRY_CopyBytes2Mod }, // POR/r { 0xEC, ENTRY_CopyBytes2Mod }, // PADDSB/r { 0xED, ENTRY_CopyBytes2Mod }, // PADDSW/r { 0xEE, ENTRY_Invalid }, // _EE { 0xEF, ENTRY_CopyBytes2Mod }, // PXOR/r { 0xF0, ENTRY_Invalid }, // _F0 { 0xF1, ENTRY_CopyBytes2Mod }, // PSLLW/r { 0xF2, ENTRY_CopyBytes2Mod }, // PSLLD/r { 0xF3, ENTRY_CopyBytes2Mod }, // PSLLQ/r { 0xF4, ENTRY_Invalid }, // _F4 { 0xF5, ENTRY_CopyBytes2Mod }, // PMADDWD/r { 0xF6, ENTRY_Invalid }, // _F6 { 0xF7, ENTRY_Invalid }, // _F7 { 0xF8, ENTRY_CopyBytes2Mod }, // PSUBB/r { 0xF9, ENTRY_CopyBytes2Mod }, // PSUBW/r { 0xFA, ENTRY_CopyBytes2Mod }, // PSUBD/r { 0xFB, ENTRY_Invalid }, // _FB { 0xFC, ENTRY_CopyBytes2Mod }, // PADDB/r { 0xFD, ENTRY_CopyBytes2Mod }, // PADDW/r { 0xFE, ENTRY_CopyBytes2Mod }, // PADDD/r { 0xFF, ENTRY_Invalid }, // _FF { 0, ENTRY_End }, }; BOOL CDetourDis::SanityCheckSystem(){ for(ULONG n = 0; n < 256; n++){ REFCOPYENTRY pEntry = &s_rceCopyTable[n]; if(n != pEntry->nOpcode){ ASSERT(n == pEntry->nOpcode); return FALSE; } } if(s_rceCopyTable[256].pfCopy != NULL){ ASSERT(!"Missing end marker."); return FALSE; } for(n = 0; n < 256; n++){ REFCOPYENTRY pEntry = &s_rceCopyTable0F[n]; if(n != pEntry->nOpcode){ ASSERT(n == pEntry->nOpcode); return FALSE; } } if(s_rceCopyTable0F[256].pfCopy != NULL){ ASSERT(!"Missing end marker."); return FALSE; } return TRUE; }
Code:
////////////////////////////////////////////////////////////////////////////// // // Module: detours.lib // File: disasm.h // // Detours for binary functions. Version 1.5 (Build 46) // Includes support for all x86 chips prior to the Pentium III. // // Copyright 1999-2001, Microsoft Corporation // #pragma once #ifndef _DISASM_H_ #define _DISASM_H_ class CDetourDis { public: CDetourDis(PBYTE* ppbTarget, LONG* plExtra); PBYTE CopyInstruction(PBYTE pbDst, PBYTE pbSrc); PBYTE CopyInstructionEx(PBYTE pbDst, PBYTE pbSrc, PBYTE pbDstOverride); PBYTE CopyInstructionZero(PBYTE pbDst, PBYTE pbSrc); BYTE InstructionLen(PBYTE pbSrc); static BOOL SanityCheckSystem(); public: struct COPYENTRY; typedef const COPYENTRY* REFCOPYENTRY; typedef PBYTE (CDetourDis::* COPYFUNC)(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); enum { DYNAMIC = 0x1u, ADDRESS = 0x2u, NOENLARGE = 0x4u, SIB = 0x10u, NOTSIB = 0x0fu, }; struct COPYENTRY { ULONG nOpcode : 8; // Opcode ULONG nFixedSize : 3; // Fixed size of opcode ULONG nFixedSize16 : 3; // Fixed size when 16 bit operand ULONG nModOffset : 3; // Offset to mod/rm byte (0=none) LONG nRelOffset : 3; // Offset to relative target. ULONG nFlagBits : 4; // Flags for DYNAMIC, etc. COPYFUNC pfCopy; // Function pointer. }; protected: #define ENTRY_CopyBytes1 1, 1, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes1Dynamic 1, 1, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes2 2, 2, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes2Jump 2, 2, 0, 1, 0, CopyBytes #define ENTRY_CopyBytes2CantJump 2, 2, 0, 1, NOENLARGE, CopyBytes #define ENTRY_CopyBytes2Dynamic 2, 2, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes3 3, 3, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes3Dynamic 3, 3, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes3Or5 5, 3, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes3Or5Target 5, 3, 0, 1, 0, CopyBytes #define ENTRY_CopyBytes5Or7Dynamic 7, 5, 0, 0, DYNAMIC, CopyBytes #define ENTRY_CopyBytes3Or5Address 5, 3, 0, 0, ADDRESS, CopyBytes #define ENTRY_CopyBytes4 4, 4, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes5 5, 5, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes7 7, 7, 0, 0, 0, CopyBytes #define ENTRY_CopyBytes2Mod 2, 2, 1, 0, 0, CopyBytes #define ENTRY_CopyBytes2Mod1 3, 3, 1, 0, 0, CopyBytes #define ENTRY_CopyBytes2ModOperand 6, 4, 1, 0, 0, CopyBytes #define ENTRY_CopyBytes3Mod 3, 3, 2, 0, 0, CopyBytes #define ENTRY_CopyBytesPrefix 1, 1, 0, 0, 0, CopyBytesPrefix #define ENTRY_Copy0F 1, 1, 0, 0, 0, Copy0F #define ENTRY_Copy66 1, 1, 0, 0, 0, Copy66 #define ENTRY_Copy67 1, 1, 0, 0, 0, Copy67 #define ENTRY_CopyF6 0, 0, 0, 0, 0, CopyF6 #define ENTRY_CopyF7 0, 0, 0, 0, 0, CopyF7 #define ENTRY_CopyFF 0, 0, 0, 0, 0, CopyFF #define ENTRY_Invalid 1, 1, 0, 0, 0, Invalid #define ENTRY_End 0, 0, 0, 0, 0, NULL PBYTE CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE Invalid(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE AdjustTarget(PBYTE pbDst, PBYTE pbSrc, LONG cbOp, LONG cbTargetOffset); VOID Set16BitOperand(); VOID Set32BitOperand(); VOID Set16BitAddress(); VOID Set32BitAddress(); protected: PBYTE Copy0F(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE Copy66(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE Copy67(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); protected: static const COPYENTRY s_rceCopyTable[257]; static const COPYENTRY s_rceCopyTable0F[257]; static const BYTE s_rbModRm[256]; protected: BOOL m_b16BitOperand; BOOL m_b16BitAddress; PBYTE* m_ppbTarget; LONG* m_plExtra; LONG m_lScratchExtra; PBYTE m_pbScratchTarget; BYTE m_rbScratchDst[64]; BYTE* m_pbDstOverride; BOOL m_bAdjustZero; }; ////////////////////////////////////////////////////////////////////////////// enum { OP_PRE_ES = 0x26, OP_PRE_CS = 0x2e, OP_PRE_SS = 0x36, OP_PRE_DS = 0x3e, OP_PRE_FS = 0x64, OP_PRE_GS = 0x65, OP_JMP_SEG = 0x25, OP_JA = 0x77, OP_NOP = 0x90, OP_CALL = 0xe8, OP_JMP = 0xe9, OP_PREFIX = 0xff, OP_MOV_EAX = 0xa1, OP_SET_EAX = 0xb8, OP_JMP_EAX = 0xe0, OP_RET_POP = 0xc2, OP_RET = 0xc3, OP_BRK = 0xcc, SIZE_OF_JMP = 5, SIZE_OF_NOP = 1, SIZE_OF_BRK = 1, SIZE_OF_TRP_OPS = SIZE_OF_JMP /* + SIZE_OF_BRK */, }; ////////////////////////////////////////////////////////////////////////////// inline PBYTE DetourGenMovEax(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xB8; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEbx(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBB; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEcx(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xB9; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEdx(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBA; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEsi(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBE; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEdi(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBF; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEbp(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBD; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenMovEsp(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0xBC; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenPush(PBYTE pbCode, UINT32 nValue){ *pbCode++ = 0x68; *((UINT32*&)pbCode)++ = nValue; return pbCode; } inline PBYTE DetourGenPushad(PBYTE pbCode){ *pbCode++ = 0x60; return pbCode; } inline PBYTE DetourGenPopad(PBYTE pbCode){ *pbCode++ = 0x61; return pbCode; } inline PBYTE DetourGenJmp(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0){ if(pbJmpSrc == 0) pbJmpSrc = pbCode; *pbCode++ = 0xE9; *((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5); return pbCode; } inline PBYTE DetourGenCall(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0){ if(pbJmpSrc == 0) pbJmpSrc = pbCode; *pbCode++ = 0xE8; *((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5); return pbCode; } inline PBYTE DetourGenBreak(PBYTE pbCode){ *pbCode++ = 0xcc; return pbCode; } inline PBYTE DetourGenRet(PBYTE pbCode){ *pbCode++ = 0xc3; return pbCode; } inline PBYTE DetourGenNop(PBYTE pbCode){ *pbCode++ = 0x90; return pbCode; } #define DETOUR_INSTRUCTION_TARGET_NONE ((PBYTE)0) #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PBYTE)~0ul) #endif //_DISASM_H_--------------------------------------------------------------------------------------------------------------
Todas as funções e endereços
Usado para codificação em MatchServer
Exemplo:
sourcefiles.txt
Code:
*** SOURCE FILES Compiland = .\Release\MatchServer.res Compiland = .\Release\MBMatchAuth.obj c:\teamworks\stable\matchserver\mbmatchauth.h c:\teamworks\stable\matchserver\mbmatchauth.cpp Compiland = .\Release\MMatchServer_Schedule.obj c:\teamworks\stable\matchserver\mmatchserver_schedule.cpp c:\teamworks\stable\cscommon\include\mmatchobject.h Compiland = .\Release\MBMatchServerConfigReloader.obj c:\teamworks\stable\matchserver\mbmatchserverconfigreloader.cpp c:\program files\microsoft visual studio .net 2003\vc7\include\xtree c:\teamworks\stable\cscommon\include\mmatchantihack.h c:\teamworks\stable\matchserver\mbmatchserverconfigreloader.h c:\program files\microsoft visual studio .net 2003\vc7\include\stdexcept c:\teamworks\stable\cscommon\include\mmatchevent.h c:\program files\microsoft visual studio .net 2003\vc7\include\vector Compiland = .\Release\MBMatchServer_ServerKeeper.obj c:\teamworks\stable\cscommon\include\muid.h c:\teamworks\stable\cscommon\include\mcommandparameter.h c:\teamworks\stable\cscommon\include\mmatchobject.h c:\program files\microsoft visual studio .net 2003\vc7\include\vector c:\teamworks\stable\cml\include\mempool.h c:\teamworks\stable\matchserver\mbmatchserver_serverkeeper.cpp c:\program files\microsoft visual studio .net 2003\vc7\include\xstring c:\program files\microsoft visual studio .net 2003\vc7\include\xmemory c:\program files\microsoft visual studio .net 2003\vc7\include\xutility c:\program files\microsoft visual studio .net 2003\vc7\include\memory Compiland = .\Release\MBMatchServer_OnCommand.obj c:\teamworks\stable\matchserver\mbmatchserver_oncommand.cpp c:\teamworks\stable\cscommon\include\mmatchobject.h
Blasper
[0]OneWhoSighs
Assinar:
Comentários (Atom)





