Compare commits
10 Commits
ff48fc1d25
...
a08eb9c220
| Author | SHA1 | Date |
|---|---|---|
|
|
a08eb9c220 | |
|
|
a1b9f7a32d | |
|
|
26aea31550 | |
|
|
c1943df644 | |
|
|
1abb153d76 | |
|
|
b1422411a2 | |
|
|
a526a65f3e | |
|
|
9a08d162ad | |
|
|
91d57c13f0 | |
|
|
e17ffc3965 |
222
test/BASE64.cpp
222
test/BASE64.cpp
|
|
@ -8,18 +8,22 @@
|
|||
|
||||
using namespace LenheartBase;
|
||||
|
||||
|
||||
// 加解密函数签名
|
||||
typedef int (*RSA_encryptOrDecrypt)(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding);
|
||||
|
||||
|
||||
// 编解码转换表
|
||||
unsigned char CBASE64::s_encTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
unsigned char CBASE64::s_decTable[] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F,
|
||||
0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
|
||||
0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
|
||||
0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
|
||||
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
// 执行BASE64编码操作
|
||||
std::string CBASE64::encode(const std::string& str)
|
||||
|
|
@ -103,8 +107,10 @@ int CBASE64::__decode(unsigned char* pDest, const unsigned char* pSrc, size_t nS
|
|||
size_t off = 0;
|
||||
for (; off + 4 <= len; off += 4)
|
||||
{
|
||||
if ((src[0] > 0x7F) || (src[1] > 0x7F) || (src[2] > 0x7F) || (src[3] > 0x7F)) return (int)(dst - odst);
|
||||
if ((src[0] == '=') || (src[1] == '=') || (src[2] == '=') || (src[3] == '=')) break;
|
||||
if ((src[0] > 0x7F) || (src[1] > 0x7F) || (src[2] > 0x7F) || (src[3] > 0x7F))
|
||||
return (int)(dst - odst);
|
||||
if ((src[0] == '=') || (src[1] == '=') || (src[2] == '=') || (src[3] == '='))
|
||||
break;
|
||||
|
||||
l = s_decTable[*src++];
|
||||
m = s_decTable[*src++];
|
||||
|
|
@ -150,7 +156,6 @@ int CBASE64::__decode(unsigned char* pDest, const unsigned char* pSrc, size_t nS
|
|||
return (int)(dst - odst);
|
||||
}
|
||||
|
||||
|
||||
std::string CBASE64::RsaPriDecrypt(const std::string& cipher_text, const std::string& pri_key)
|
||||
{
|
||||
std::string decrypt_text;
|
||||
|
|
@ -159,7 +164,8 @@ std::string CBASE64::RsaPriDecrypt(const std::string& cipher_text, const std::st
|
|||
keybio = BIO_new_mem_buf((unsigned char*)pri_key.c_str(), -1);
|
||||
|
||||
rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
|
||||
if (rsa == nullptr) {
|
||||
if (rsa == nullptr)
|
||||
{
|
||||
unsigned long err = ERR_get_error(); //获取错误号
|
||||
char err_msg[1024] = { 0 };
|
||||
ERR_error_string(err, err_msg); // 格式:error:errId:库:函数:原因
|
||||
|
|
@ -174,13 +180,15 @@ std::string CBASE64::RsaPriDecrypt(const std::string& cipher_text, const std::st
|
|||
std::string sub_str;
|
||||
unsigned int pos = 0;
|
||||
// 对密文进行分段解密
|
||||
while (pos < cipher_text.length() - 1) {
|
||||
while (pos < cipher_text.length() - 1)
|
||||
{
|
||||
sub_str = cipher_text.substr(pos, key_len);
|
||||
memset(sub_text, 0, key_len + 1);
|
||||
ret = RSA_private_decrypt(sub_str.length(), (const unsigned char*)sub_str.c_str(), (unsigned char*)sub_text, rsa, 1);
|
||||
if (ret >= 0) {
|
||||
if (ret >= 0)
|
||||
{
|
||||
decrypt_text.append(std::string(sub_text, ret));
|
||||
//printf("pos:%d, Length: %d ,sub: %s\n", pos, cipher_text.length(),sub_text);
|
||||
// printf("pos:%d, Length: %d ,sub: %s\n", pos, cipher_text.length(),sub_text);
|
||||
pos += key_len;
|
||||
}
|
||||
}
|
||||
|
|
@ -206,7 +214,7 @@ std::string CBASE64::RsaPriEncrypt(const std::string& clear_text, const std::str
|
|||
|
||||
// 获取RSA单次可以处理的数据块的最大长度
|
||||
int key_len = RSA_size(rsa);
|
||||
int block_len = key_len - 11; // 因为填充方式为RSA_PKCS1_PADDING, 所以要在key_len基础上减去11
|
||||
int block_len = key_len - 11; // 因为填充方式为RSA_PKCS1_PADDING, 所以要在key_len基础上减去11
|
||||
|
||||
// 申请内存:存贮加密后的密文数据
|
||||
char* sub_text = new char[key_len + 1];
|
||||
|
|
@ -215,11 +223,13 @@ std::string CBASE64::RsaPriEncrypt(const std::string& clear_text, const std::str
|
|||
unsigned int pos = 0;
|
||||
std::string sub_str;
|
||||
// 对数据进行分段加密(返回值是加密后数据的长度)
|
||||
while (pos < clear_text.length()) {
|
||||
while (pos < clear_text.length())
|
||||
{
|
||||
sub_str = clear_text.substr(pos, block_len);
|
||||
memset(sub_text, 0, key_len + 1);
|
||||
ret = RSA_private_encrypt(sub_str.length(), (const unsigned char*)sub_str.c_str(), (unsigned char*)sub_text, rsa, RSA_PKCS1_PADDING);
|
||||
if (ret >= 0) {
|
||||
if (ret >= 0)
|
||||
{
|
||||
encrypt_text.append(std::string(sub_text, ret));
|
||||
}
|
||||
pos += block_len;
|
||||
|
|
@ -232,3 +242,177 @@ std::string CBASE64::RsaPriEncrypt(const std::string& clear_text, const std::str
|
|||
|
||||
return encrypt_text;
|
||||
}
|
||||
|
||||
// 生成RSA密钥结构
|
||||
void* CBASE64::__genKey(int nBits)
|
||||
{
|
||||
RSA* rsa = RSA_new();
|
||||
|
||||
BIGNUM* bne = BN_new();
|
||||
BN_set_word(bne, RSA_F4);
|
||||
|
||||
int ret = RSA_generate_key_ex(rsa, nBits, bne, NULL);
|
||||
|
||||
BN_free(bne);
|
||||
|
||||
if (ret != 1)
|
||||
{
|
||||
RSA_free(rsa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void*)rsa;
|
||||
}
|
||||
|
||||
// 生成密钥对,输出为PEM字符串
|
||||
bool CBASE64::genKeyStrings(std::string& strPrivateKeyPEMString, std::string& strPublicKeyPEMString)
|
||||
{
|
||||
// 生成RSA
|
||||
RSA* rsa = (RSA*)__genKey(1024);
|
||||
if (rsa == NULL)
|
||||
return false;
|
||||
|
||||
// 输出私钥
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
int ret = PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL);
|
||||
if (ret != 1)
|
||||
{
|
||||
BIO_free(bio);
|
||||
RSA_free(rsa);
|
||||
return false;
|
||||
}
|
||||
|
||||
char sBuf[1024] = { 0 };
|
||||
int bytes = BIO_read(bio, sBuf, 1024);
|
||||
if (bytes <= 0)
|
||||
{
|
||||
BIO_free(bio);
|
||||
RSA_free(rsa);
|
||||
return false;
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
strPrivateKeyPEMString.assign(sBuf, bytes);
|
||||
}
|
||||
|
||||
// 输出公钥
|
||||
{
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
int ret = PEM_write_bio_RSAPublicKey(bio, rsa);
|
||||
if (ret != 1)
|
||||
{
|
||||
BIO_free(bio);
|
||||
RSA_free(rsa);
|
||||
return false;
|
||||
}
|
||||
|
||||
char sBuf[1024] = { 0 };
|
||||
int bytes = BIO_read(bio, sBuf, 1024);
|
||||
if (bytes <= 0)
|
||||
{
|
||||
BIO_free(bio);
|
||||
RSA_free(rsa);
|
||||
return false;
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
strPublicKeyPEMString.assign(sBuf, bytes);
|
||||
}
|
||||
|
||||
RSA_free(rsa);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 使用PEM私钥字符串加密
|
||||
bool CBASE64::encryptByPrivatePEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString)
|
||||
{
|
||||
// 加载私钥
|
||||
BIO* bio = BIO_new_mem_buf((const void*)strKeyPEMString.data(), strKeyPEMString.size());
|
||||
RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
|
||||
if (rsa == NULL)
|
||||
return false;
|
||||
|
||||
// 使用私钥加密
|
||||
bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void*)RSA_private_encrypt, true);
|
||||
RSA_free(rsa);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
// 使用RSA执行加密或解密
|
||||
bool CBASE64::__encryptOrDecrypt(const std::string& strIn, std::string& strOut, const void* pRSA, const void* pFunc, bool bEncrypt)
|
||||
{
|
||||
const RSA_encryptOrDecrypt encryptOrDecrypt = (const RSA_encryptOrDecrypt)pFunc;
|
||||
|
||||
// 计算加密块大小
|
||||
int nKeySize = RSA_size((RSA*)pRSA);
|
||||
int nBlockSize = bEncrypt ? (nKeySize - RSA_PKCS1_PADDING_SIZE) : nKeySize;
|
||||
|
||||
const unsigned char* pIn = (const unsigned char*)strIn.data();
|
||||
int nInSize = strIn.size();
|
||||
|
||||
unsigned char* pBuf = new unsigned char[nKeySize];
|
||||
|
||||
// 分组迭代加密
|
||||
for (int i = 0; i < nInSize; )
|
||||
{
|
||||
int nBlockLen = (nInSize - i > nBlockSize ? nBlockSize : nInSize - i);
|
||||
|
||||
int ret = encryptOrDecrypt(nBlockLen, pIn + i, pBuf, (RSA*)pRSA, RSA_PKCS1_PADDING);
|
||||
if (ret <= 0)
|
||||
{
|
||||
delete[] pBuf;
|
||||
return false;
|
||||
}
|
||||
|
||||
strOut.append((char*)pBuf, ret);
|
||||
i += nBlockLen;
|
||||
}
|
||||
|
||||
delete[] pBuf;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 使用PEM公钥字符串加密
|
||||
bool CBASE64::encryptByPublicPEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString)
|
||||
{
|
||||
// 加载公钥
|
||||
BIO* bio = BIO_new_mem_buf((const void*)strKeyPEMString.data(), strKeyPEMString.size());
|
||||
RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
|
||||
if (rsa == NULL)
|
||||
return false;
|
||||
|
||||
// 使用公钥加密
|
||||
bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void*)RSA_public_encrypt, true);
|
||||
RSA_free(rsa);
|
||||
return b;
|
||||
}
|
||||
|
||||
// 使用PEM公钥字符串解密
|
||||
bool CBASE64::decryptByPublicPEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString)
|
||||
{
|
||||
// 加载公钥
|
||||
BIO* bio = BIO_new_mem_buf((const void*)strKeyPEMString.data(), strKeyPEMString.size());
|
||||
RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
|
||||
if (rsa == NULL)
|
||||
return false;
|
||||
|
||||
// 检查密文大小是否为分组的整数倍
|
||||
int keySize = RSA_size(rsa);
|
||||
int blockSize = keySize;
|
||||
if ((strIn.size() % blockSize) != 0)
|
||||
return false;
|
||||
|
||||
// 使用公钥解密
|
||||
bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void*)RSA_public_decrypt, false);
|
||||
RSA_free(rsa);
|
||||
return b;
|
||||
}
|
||||
|
|
@ -9,6 +9,11 @@ namespace LenheartBase
|
|||
class CBASE64
|
||||
{
|
||||
public:
|
||||
// 生成RSA密钥结构
|
||||
static void* __genKey(int nBits);
|
||||
|
||||
// 生成密钥对,输出为PEM字符串
|
||||
static bool genKeyStrings(std::string& strPrivateKeyPEMString, std::string& strPublicKeyPEMString);
|
||||
|
||||
// 执行BASE64编码操作
|
||||
static std::string encode(const std::string& str);
|
||||
|
|
@ -20,8 +25,20 @@ namespace LenheartBase
|
|||
static std::string RsaPriDecrypt(const std::string& cipher_text, const std::string& pri_key);
|
||||
// 执行RSA私匙加密操作
|
||||
static std::string RsaPriEncrypt(const std::string& clear_text, const std::string& pri_key);
|
||||
private:
|
||||
|
||||
// 使用PEM私钥字符串加密
|
||||
static bool encryptByPrivatePEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString);
|
||||
|
||||
// 使用PEM公钥字符串加密
|
||||
static bool encryptByPublicPEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString);
|
||||
|
||||
// 使用PEM公钥字符串解密
|
||||
static bool decryptByPublicPEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString);
|
||||
|
||||
// 使用RSA执行加密或解密
|
||||
static bool __encryptOrDecrypt(const std::string& strIn, std::string& strOut, const void* pRSA, const void* pFunc, bool bEncrypt);
|
||||
|
||||
private:
|
||||
// 分组编码
|
||||
static int __encode(unsigned char* pDest, const unsigned char* pSrc, size_t nSrcLen);
|
||||
|
||||
|
|
@ -29,7 +46,6 @@ namespace LenheartBase
|
|||
static int __decode(unsigned char* pDest, const unsigned char* pSrc, size_t nSrcLen);
|
||||
|
||||
private:
|
||||
|
||||
// 编解码转换表
|
||||
static unsigned char s_encTable[];
|
||||
static unsigned char s_decTable[];
|
||||
|
|
|
|||
414
test/DNFTOOL.cpp
414
test/DNFTOOL.cpp
|
|
@ -1,5 +1,202 @@
|
|||
#include "pch.h"
|
||||
#include "DNFTOOL.h"
|
||||
# define Pub_key "-----BEGIN RSA PUBLIC KEY-----\nMIGJAoGBAMiYuNW4K1rST7ZWYpWX6nEziXi5JveLPhDCLj0VZ/5/4dzBWrmoL/Ic\nFZuHOBJtYHm965713kKC9gtw2EyVgkqmXLT3105jEUqzNizfThc6C2ZL6vMmzUZl\nooxNyaOC5mWthPZtwlqQihYWT2nW/wKp8fpTouXihQOCPjqdRoVFAgMBAAE=\n-----END RSA PUBLIC KEY-----"
|
||||
extern bool Sinw = false;
|
||||
|
||||
std::string DNFTOOL::GetUserIp()
|
||||
{
|
||||
std::string ippack;
|
||||
//获取ExeIP
|
||||
int gameip = *(int*)0x1AE9CEC;
|
||||
|
||||
/*
|
||||
std::cout << gameip << std::endl;
|
||||
//单独定制的脱机IP
|
||||
if (gameip == 3735605)
|
||||
{
|
||||
|
||||
|
||||
Sinw = true;
|
||||
//int skey[] = Skey;//定义解密数组
|
||||
//Cutecode(nutstr, skey);//解密
|
||||
|
||||
//wchar_t* sfile = DNFTOOL::charTowchar_t((char*)"TTTT");
|
||||
//wchar_t* ss = DNFTOOL::charTowchar_t((char*)nutstr);
|
||||
|
||||
//wprintf(L"Function:%s \n", ss);
|
||||
//uint32_t v = GetSqVm();
|
||||
//squirrel::SQdofileBuffer(v, sfile, ss);
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
int a = 10;
|
||||
int b[2] = { 1,2 };
|
||||
while (true)
|
||||
{
|
||||
b[a] = -999999;
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//如果ExeIP 等于 192.168.200.131
|
||||
if (gameip == 3735601)
|
||||
{
|
||||
//获取本机IP
|
||||
std::string MyIp;
|
||||
httplib::Client* IPCliObj = NULL;// http连接主体
|
||||
IPCliObj = new httplib::Client("myip.ipip.net");//初始化 http 对象
|
||||
auto MyIpres = IPCliObj->Get("/");
|
||||
if (MyIpres->status == 200)//如果返回包正常
|
||||
{
|
||||
MyIp = MyIpres->body;//取得date
|
||||
}
|
||||
|
||||
//std::cout << "本机IP:" << MyIp << std::endl;
|
||||
//已经得到了本机IP
|
||||
|
||||
int Pos = MyIp.find("IP", 0) + 5;
|
||||
MyIp = MyIp.substr(Pos, MyIp.find(" ", Pos) - Pos);
|
||||
|
||||
ippack = MyIp;
|
||||
}
|
||||
else
|
||||
{
|
||||
//wchar_t* wgameip = (wchar_t*)0x1AE9CEC;
|
||||
wchar_t* wgameip = (wchar_t*)0x15A73A4;
|
||||
DNFTOOL::Wchar_tToString(ippack, wgameip);
|
||||
}
|
||||
|
||||
return ippack;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//std::string basejiaoben;
|
||||
bool jiaoben = false;
|
||||
std::vector<std::string> BaseData;
|
||||
|
||||
|
||||
void Unski(std::string Body) {
|
||||
std::vector<std::string> BaseDataBuffer;
|
||||
DNFTOOL::Split(Body, BaseDataBuffer, "$$$$$");
|
||||
|
||||
size_t Ds = BaseDataBuffer.size();
|
||||
|
||||
for (size_t i = 0; i < Ds; i++)
|
||||
{
|
||||
std::string filename = "BaseData" + std::to_string(i);
|
||||
std::string str = BaseDataBuffer[i];
|
||||
|
||||
str = str.substr(str.find("[") + 1, str.length() - 2);
|
||||
|
||||
std::vector<std::string> Data;
|
||||
DNFTOOL::Split(str, Data, ", ");
|
||||
size_t Ds = Data.size();
|
||||
|
||||
char* nutstr = new char[Ds + 1];
|
||||
|
||||
|
||||
for (size_t s = 0; s < Ds; s++)
|
||||
{
|
||||
nutstr[s] = char(atoi(Data[s].c_str()));
|
||||
}
|
||||
nutstr[Ds] = '\0';
|
||||
|
||||
int skey[] = Skey;//定义解密数组
|
||||
Cutecode(nutstr, skey);//解密
|
||||
|
||||
BaseData.push_back(nutstr);
|
||||
}
|
||||
|
||||
jiaoben = true;
|
||||
}
|
||||
|
||||
|
||||
bool DNFTOOL::ReqIpLicense(std::string ippack,std::string Rqip)
|
||||
{
|
||||
LenheartBase::CBASE64 bb;
|
||||
std::string New = "";
|
||||
bb.encryptByPublicPEMString(ippack, New, Pub_key);
|
||||
std::string enstring = bb.encode(New);
|
||||
|
||||
|
||||
httplib::Client* CliObj = NULL;// http连接主体
|
||||
CliObj = new httplib::Client(Rqip);//初始化 http 对象
|
||||
httplib::Params ParamsObj;//新建 Params 对象
|
||||
ParamsObj.emplace("ip", enstring.c_str());//加入账号数据进数据包
|
||||
|
||||
CliObj->set_connection_timeout(0, 1000000); // 300 milliseconds
|
||||
CliObj->set_read_timeout(5, 0); // 5 seconds
|
||||
CliObj->set_write_timeout(5, 0); // 5 seconds
|
||||
|
||||
auto res = CliObj->Post("/user/de", ParamsObj);
|
||||
|
||||
if (res) {
|
||||
|
||||
if (res->status == 200)//如果返回包正常
|
||||
{
|
||||
std::string date = res->body;//取得date
|
||||
|
||||
rapidjson::Document Dom;
|
||||
Dom.Parse(date.c_str());//加载 字符串
|
||||
|
||||
std::string base64code = bb.decode(Dom["verify"].GetString());
|
||||
std::string verify = "";
|
||||
bb.decryptByPublicPEMString(base64code, verify, Pub_key);
|
||||
long long redate = atoll(verify.c_str()) / 1000;
|
||||
time_t myt = time(0);
|
||||
long long nowdate = (long long)myt;
|
||||
__int64 absnum = abs(nowdate - redate);
|
||||
|
||||
if (absnum < 18000)
|
||||
{
|
||||
#ifdef SELL
|
||||
httplib::Params nParamsObj;//新建 Params 对象
|
||||
nParamsObj.emplace("ip", enstring.c_str());//加入账号数据进数据包
|
||||
auto nres = CliObj->Post("/user/dr", nParamsObj);
|
||||
|
||||
if (nres->status == 200)//如果返回包正常
|
||||
{
|
||||
Unski(nres->body);
|
||||
}
|
||||
#endif // SELL
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//int a = 10;
|
||||
//int b[2] = { 1,2 };
|
||||
//while (true)
|
||||
//{
|
||||
// b[a] = -999999;
|
||||
// a++;
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//int a = 10;
|
||||
//int b[2] = { 1,2 };
|
||||
//while (true)
|
||||
//{
|
||||
// b[a] = -999999;
|
||||
// a++;
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int DNFTOOL::GetExeNutWrtNum(int Pos)
|
||||
{
|
||||
|
|
@ -48,6 +245,11 @@ int DNFTOOL::GetHook(int Addr, std::string
|
|||
{
|
||||
for (int z = 0; z < i; z++)
|
||||
{
|
||||
if (num <= 0 && z != i - 1)//可能读取发生了错误
|
||||
{
|
||||
num = 0;
|
||||
return num;
|
||||
}
|
||||
if (z == i - 1)
|
||||
{
|
||||
if (Type == 0)return *(int*)(num + GetHookArr[z]);
|
||||
|
|
@ -180,39 +382,39 @@ int DNFTOOL::GetEquAddr(int addr)
|
|||
return 0x3064;
|
||||
break;
|
||||
case 12:
|
||||
return 0x3038;
|
||||
return 0x303c;
|
||||
break;
|
||||
|
||||
|
||||
case 13:
|
||||
return 0x3008;
|
||||
break;
|
||||
case 14:
|
||||
return 0x300C;
|
||||
break;
|
||||
case 15:
|
||||
case 13://帽子
|
||||
return 0x3010;
|
||||
break;
|
||||
case 16:
|
||||
case 14://头部
|
||||
return 0x3014;
|
||||
break;
|
||||
case 17:
|
||||
case 15://脸
|
||||
return 0x3018;
|
||||
break;
|
||||
case 18:
|
||||
return 0x301C;
|
||||
case 16:
|
||||
return 0x301c;
|
||||
break;
|
||||
case 19:
|
||||
case 17:
|
||||
return 0x3020;
|
||||
break;
|
||||
case 20:
|
||||
case 18:
|
||||
return 0x3024;
|
||||
break;
|
||||
case 21:
|
||||
case 19:
|
||||
return 0x3028;
|
||||
break;
|
||||
case 20:
|
||||
return 0x302c;
|
||||
break;
|
||||
case 21:
|
||||
return 0x3030;
|
||||
break;
|
||||
case 22:
|
||||
return 0x302C;
|
||||
return 0x3034;
|
||||
break;
|
||||
case 23:
|
||||
return 0x3030;
|
||||
|
|
@ -233,6 +435,37 @@ int DNFTOOL::GetEquAddr(int addr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
char* DNFTOOL::U8ToUnicode(const char* szU8)
|
||||
{
|
||||
//UTF8 to Unicode
|
||||
//预转换,得到所需空间的大小
|
||||
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
|
||||
//分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间
|
||||
wchar_t* wszString = new wchar_t[wcsLen + 1];
|
||||
//转换
|
||||
::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
|
||||
//最后加上'\0'
|
||||
wszString[wcsLen] = '\0';
|
||||
|
||||
char* m_char;
|
||||
int len = WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
|
||||
m_char = new char[len + 1];
|
||||
WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), m_char, len, NULL, NULL);
|
||||
delete []wszString;
|
||||
m_char[len] = '\0';
|
||||
return m_char;
|
||||
}
|
||||
|
||||
char* DNFTOOL::UnicodeToUtf8(const wchar_t* unicode)
|
||||
{
|
||||
int len;
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);
|
||||
char* szUtf8 = (char*)malloc(len + 1);
|
||||
memset(szUtf8, 0, len + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, unicode, -1, szUtf8, len, NULL, NULL);
|
||||
return szUtf8;
|
||||
}
|
||||
|
||||
char* DNFTOOL::UnicodeToAnsi(const wchar_t* szStr, char* pResult, int maxLen)
|
||||
{
|
||||
if (NULL == pResult)
|
||||
|
|
@ -305,10 +538,35 @@ wchar_t* DNFTOOL::SquirrelW2W(const wchar_t* Str)
|
|||
}
|
||||
cbuffer[len / 2] = '\0';
|
||||
wchar_t* str = DNFTOOL::char2wchar(cbuffer);
|
||||
delete cbuffer;
|
||||
delete []cbuffer;
|
||||
return str;
|
||||
}
|
||||
|
||||
char* DNFTOOL::SquirrelU2W(const wchar_t* Str)
|
||||
{
|
||||
size_t len = 0;
|
||||
char* wbuffer = (char*)(Str);
|
||||
while (true)
|
||||
{
|
||||
if (wbuffer[len] == 0 && wbuffer[len - 1] == 0)break;
|
||||
++len;
|
||||
}
|
||||
char* cbuffer = new char[len / 2 + 1];
|
||||
int k = 0;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
cbuffer[k] = wbuffer[i];
|
||||
++k;
|
||||
}
|
||||
}
|
||||
cbuffer[len / 2] = '\0';
|
||||
char* Text = U8ToUnicode(cbuffer);
|
||||
delete []cbuffer;
|
||||
return Text;
|
||||
}
|
||||
|
||||
wchar_t* DNFTOOL::AnsiToUnicode(const char* szStr, wchar_t* pResult, int maxLen)
|
||||
{
|
||||
if (NULL == pResult)
|
||||
|
|
@ -346,26 +604,80 @@ void DNFTOOL::GMNotice(char* str, int type, int color)
|
|||
_Noticecall(thisc, 0, str, color, type, 0, 0, 0);
|
||||
}
|
||||
|
||||
#if defined LOCALHOSTS_SWITCH
|
||||
std::string DNFTOOL::ReplaceAllword(const std::string& resources, const std::string& key, const std::string& ReplaceKey)
|
||||
{
|
||||
size_t pos = 0;
|
||||
std::string temp = resources;
|
||||
while ((pos = temp.find(key, pos)) != std::string::npos)
|
||||
{
|
||||
temp.erase(pos, key.size());//删除原有字符串
|
||||
temp.insert(pos, ReplaceKey);//插入替换字符串
|
||||
pos += ReplaceKey.size(); //更新查询起始标志位
|
||||
}
|
||||
return temp;
|
||||
|
||||
#else
|
||||
}
|
||||
|
||||
|
||||
std::string BAKIP()
|
||||
{
|
||||
////std::cout << "获取Ip" << std::endl;
|
||||
//httplib::SSLClient Tencword("gitee.com");
|
||||
//std::string body;
|
||||
//auto res = Tencword.Get("/yosin_team/request-ip/raw/master/README.md",
|
||||
// [&](const char* data, size_t data_length) {
|
||||
// body.append(data, data_length);
|
||||
// return true;
|
||||
// });
|
||||
//if (!body.empty())
|
||||
//{
|
||||
// return body;
|
||||
//}
|
||||
//else
|
||||
// return DNFTOOL::GetIP();
|
||||
}
|
||||
std::string DNFTOOL::GetIP()
|
||||
{
|
||||
httplib::SSLClient Tencword("gitee.com");
|
||||
std::string body;
|
||||
auto res = Tencword.Get("/yosin_team/request-ip/raw/master/README.md",
|
||||
[&](const char* data, size_t data_length) {
|
||||
body.append(data, data_length);
|
||||
return true;
|
||||
});
|
||||
if (!body.empty())
|
||||
{
|
||||
return body;
|
||||
std::ifstream inFile;
|
||||
inFile.open("DFC180.dll"); // 默认当方式打开文件
|
||||
if (!inFile.is_open()) {
|
||||
int a = 10;
|
||||
int b[2] = { 1,2 };
|
||||
while (true)
|
||||
{
|
||||
b[a] = -999999;
|
||||
a++;
|
||||
}
|
||||
}
|
||||
else
|
||||
return GetIP();
|
||||
|
||||
std::string Ip;
|
||||
while (1) {
|
||||
// 从文件中读取第一个数据,并将其打印出来
|
||||
inFile >> Ip;
|
||||
if (inFile.eof()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char* uncode = (char*)Ip.c_str();
|
||||
int skey[] = DFCSkey;//定义解密数组
|
||||
|
||||
Cutecode(uncode, skey);//解密
|
||||
|
||||
Ip = uncode;
|
||||
//std::cout << "获取Ip" << std::endl;
|
||||
return Ip;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
DWORD DNFTOOL::Motify_memory_attributes(int address, DWORD attributes)
|
||||
{
|
||||
DWORD Old_attributes;
|
||||
VirtualProtect(reinterpret_cast<void*>(address), Byte_Length, attributes, &Old_attributes);
|
||||
return Old_attributes;
|
||||
}
|
||||
|
||||
|
||||
void DNFTOOL::Wchar_tToString(std::string& szDst, wchar_t* wchar)
|
||||
{
|
||||
|
|
@ -388,6 +700,20 @@ const wchar_t* DNFTOOL::GetWC(const char* c)
|
|||
return wc;
|
||||
}
|
||||
|
||||
std::string DNFTOOL::UtfToGbk(const char* utf8)
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
|
||||
wchar_t* wstr = new wchar_t[len + 1];
|
||||
memset(wstr, 0, len + 1);
|
||||
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
|
||||
len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
|
||||
char* str = new char[len + 1];
|
||||
memset(str, 0, len + 1);
|
||||
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
|
||||
if (wstr) delete[] wstr;
|
||||
return str;
|
||||
}
|
||||
|
||||
void DNFTOOL::Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator)
|
||||
{
|
||||
std::string str = src;
|
||||
|
|
@ -414,7 +740,7 @@ void DNFTOOL::Split(const std::string& src, std::vector<std::string>& dest, cons
|
|||
|
||||
bool DNFTOOL::isNum(std::string str)
|
||||
{
|
||||
for (int i = 0; i < str.size(); i++)
|
||||
for (unsigned int i = 0; i < str.size(); i++)
|
||||
{
|
||||
int tmp = (int)str[i];
|
||||
if (tmp >= 48 && tmp <= 57)
|
||||
|
|
@ -428,3 +754,25 @@ bool DNFTOOL::isNum(std::string str)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int DNFTOOL::ReadInt(int addr)
|
||||
{
|
||||
return *(int*)addr;
|
||||
}
|
||||
|
||||
void DNFTOOL::WriteInt(int addr, int buf)
|
||||
{
|
||||
*(int*)addr = buf;
|
||||
}
|
||||
|
||||
void DNFTOOL::WriteByteArr(int addr, BYTE buf[], int len)
|
||||
{
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
//std::cout << "i: " << i << "buf: " << (int)buf[i] << std::endl;
|
||||
*(BYTE*)(addr + i) = (int)buf[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -51,6 +51,13 @@ typedef void(__fastcall* DrawCode)(DWORD thisc, int Seat, int a3, int a4, int a5
|
|||
static DrawCode DrawCodeF;
|
||||
#define INIT_NUT_DRAWCODE 0x1206BD0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
constexpr int Byte_Length = 6;
|
||||
|
||||
//0x1b45b94
|
||||
class DNFTOOL
|
||||
{
|
||||
|
|
@ -58,6 +65,12 @@ private:
|
|||
|
||||
|
||||
public:
|
||||
//获取用户IP
|
||||
static std::string GetUserIp();
|
||||
|
||||
//验证IP是否通过
|
||||
static bool ReqIpLicense(std::string ippack, std::string Rqip);
|
||||
|
||||
|
||||
//获取EXE使用头 号位数据
|
||||
static int GetExeNutWrtNum(int Pos);
|
||||
|
|
@ -73,11 +86,22 @@ public:
|
|||
static int DNFDeCode(int Address);
|
||||
//加密写入
|
||||
static void DNFEnCode(int AddreSs, int Data);
|
||||
//DNFTOOL::ReadInt
|
||||
static int ReadInt(int addr);
|
||||
//DNFTOOL::WriteInt
|
||||
static void WriteInt(int addr, int buf);
|
||||
//写字节数组
|
||||
static void WriteByteArr(int addr, BYTE buf[], int len);
|
||||
|
||||
//获取装备偏移地址
|
||||
static int GetEquAddr(int addr);
|
||||
|
||||
|
||||
//UTF8转Unicode
|
||||
static char* U8ToUnicode(const char* szU8);
|
||||
//Unicode 转 UTF8
|
||||
static char* UnicodeToUtf8(const wchar_t* unicode);
|
||||
|
||||
|
||||
//wchar_t* 转 char*
|
||||
static char* UnicodeToAnsi(const wchar_t* szStr, char* pResult, int maxLen);
|
||||
|
|
@ -95,7 +119,8 @@ public:
|
|||
|
||||
//Squirrel wchar_t* 转 Unicode
|
||||
static wchar_t* SquirrelW2W(const wchar_t* wchar);
|
||||
|
||||
//Squirrel UTF8 wchar_t* 转 Unicode
|
||||
static char* SquirrelU2W(const wchar_t* wchar);
|
||||
|
||||
//wchar_t* 转 string*
|
||||
static void Wchar_tToString(std::string& szDst, wchar_t* wchar);
|
||||
|
|
@ -104,6 +129,9 @@ public:
|
|||
//string 转 wchar_t*
|
||||
static const wchar_t* GetWC(const char* c);
|
||||
|
||||
//utf8 转 gb2312
|
||||
static std::string UtfToGbk(const char* utf8);
|
||||
|
||||
//将字符串分割存入vector
|
||||
static void Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator = "->");
|
||||
//判断字符串是否为纯数字
|
||||
|
|
@ -113,7 +141,29 @@ public:
|
|||
static void WindowsNotice(char* str, int type = 0x10d, int b = 0x0);
|
||||
//GM公告
|
||||
static void GMNotice(char* str, int type, int color);
|
||||
//替换字符
|
||||
static std::string ReplaceAllword(const std::string& resources, const std::string& key, const std::string& ReplaceKey);
|
||||
//获取腾讯文档IP
|
||||
static std::string GetIP();
|
||||
|
||||
//修改内存属性 返回值是源内存属性
|
||||
static DWORD Motify_memory_attributes(int address, DWORD attributes = PAGE_EXECUTE_READWRITE);
|
||||
};
|
||||
|
||||
|
||||
|
||||
static char* GBKTOUTF8(std::string& strGBK)//转码 GBK编码转成UTF8编码
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
|
||||
wchar_t* wszUtf8 = new wchar_t[len];
|
||||
memset(wszUtf8, 0, len);
|
||||
MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, wszUtf8, len);
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL);
|
||||
char* szUtf8 = new char[len + 1];
|
||||
memset(szUtf8, 0, len + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL, NULL);
|
||||
strGBK = szUtf8;
|
||||
delete[] szUtf8;
|
||||
delete[] wszUtf8;
|
||||
return (char*)strGBK.c_str();
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Use same style for all files
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = crlf
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = true
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
name: Bug Report
|
||||
about: Report a bug in Detours
|
||||
title: "<header>: Problem"
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is. Please check that you've
|
||||
read the guidelines for submitting a bug report in the
|
||||
[Bug Reports](https://github.com/microsoft/Detours/wiki/FAQ#bug-reports) section
|
||||
of the FAQ.
|
||||
|
||||
**Command-line test case**
|
||||
```
|
||||
C:\Temp>type repro.cpp
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
void main() {
|
||||
// Replace this program with one demonstrating your actual bug report,
|
||||
// along with the following compilation command. Please leave compiler
|
||||
// version banners in the output (don't use /nologo), and include output
|
||||
// of your test program, if any.
|
||||
std::cout << "Test Case Result: ";
|
||||
if (DetourIsHelperProcess()) {
|
||||
std::cout << "Fail\n";
|
||||
} else {
|
||||
std::cout << "Pass\n";
|
||||
}
|
||||
}
|
||||
|
||||
C:\Temp>cl.exe /EHsc /W4 /WX .\repro.cpp -I. ..\lib.X64\detours.lib
|
||||
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x64
|
||||
Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
|
||||
repro.cpp
|
||||
Microsoft (R) Incremental Linker Version 14.27.29111.0
|
||||
Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
|
||||
/out:repro.exe
|
||||
repro.obj
|
||||
..\lib.X64\detours.lib
|
||||
|
||||
C:\Temp>.\repro.exe
|
||||
Test Case Result: Pass
|
||||
```
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
Alternatively, include `static_assert` or `assert` lines in your
|
||||
test case above whose failure clearly indicates the problem.
|
||||
|
||||
**Detours version**
|
||||
* Option 1: Release version
|
||||
* Displayed on the releases page: https://github.com/microsoft/Detours/releases/
|
||||
* Example:
|
||||
```
|
||||
Version 4.0.1 of Detours
|
||||
```
|
||||
|
||||
* Option 2: git commit hash
|
||||
* Example:
|
||||
```
|
||||
https://github.com/microsoft/Detours/commit/2195148
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Question
|
||||
about: Ask a question about Detours
|
||||
title: ""
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Instructions
|
||||
============
|
||||
|
||||
Please check the Wiki, especially the [FAQ](https://github.com/microsoft/Detours/wiki/FAQ), to make sure your
|
||||
question has not been answered there already.
|
||||
|
||||
If you can't find the answer to your question there, please ask your question in the [Detours GitHub Discussions](https://github.com/microsoft/Detours/discussions)
|
||||
instead of filing an issue as a question, to avoid filling up the issue tracker with questions.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<!--
|
||||
Before submitting a pull request, please ensure that:
|
||||
|
||||
* These changes introduce no known API breaks (changing the public facing
|
||||
functions return types, function parameters, renaming functions, etc.).
|
||||
|
||||
* The changes are tested.
|
||||
|
||||
* Your changes are written from scratch using only this repository.
|
||||
If your changes are derived from any other project, you *must* mention it
|
||||
here, so we can determine whether the license is compatible and what else
|
||||
needs to be done.
|
||||
-->
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
name: "Detours CodeQL Config"
|
||||
|
||||
queries:
|
||||
- uses: security-and-quality
|
||||
- uses: security-extended
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
version: 2
|
||||
updates:
|
||||
|
||||
# Maintain dependencies for GitHub Actions Automatically
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
commit-message:
|
||||
prefix: "Dependencies:"
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
name: CI-Build
|
||||
|
||||
env:
|
||||
# Turn on msvc analysis during build, enable once warnings are clean.
|
||||
DETOURS_ANALYZE: true
|
||||
|
||||
# Compile in parallel where possible.
|
||||
CL: /MP
|
||||
|
||||
# Triggers the workflow on push or pull request events for the master branch.
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019, windows-2016]
|
||||
arch: [x86, x64, x64_arm, x64_arm64]
|
||||
conf: [Release, Debug]
|
||||
|
||||
steps:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Setup build environment variables using vcvarsall.bat.
|
||||
- name: Configure MSCV Compiler for ${{ matrix.arch }}
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
- name: Initialize CodeQL for C++
|
||||
uses: github/codeql-action/init@v1
|
||||
if: ${{ matrix.os == 'windows-2019' && matrix.conf == 'Debug' }}
|
||||
with:
|
||||
languages: cpp
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Build Detours for ${{ matrix.arch }} on ${{ matrix.os }}
|
||||
env:
|
||||
# Tell detours what process to target
|
||||
DETOURS_TARGET_PROCESSOR: ${{ env.VSCMD_ARG_TGT_ARCH }}
|
||||
DETOURS_CONFIG: ${{ matrix.conf }}
|
||||
run: nmake
|
||||
|
||||
- name: Run unit tests for ${{ matrix.arch }} on ${{ matrix.os }}
|
||||
id: run-unit-tests
|
||||
env:
|
||||
DETOURS_CONFIG: ${{ matrix.conf }}
|
||||
run: cd tests && nmake test
|
||||
if: ${{ matrix.arch == 'x86' || matrix.arch == 'x64' }}
|
||||
|
||||
- name: Upload artifacts for ${{ matrix.arch }} on ${{ matrix.os }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: artifacts-${{ matrix.os }}
|
||||
path: |
|
||||
lib.*/
|
||||
bin.*/
|
||||
include/
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
if: ${{ matrix.os == 'windows-2019' && matrix.conf == 'Debug' }}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# C extensions
|
||||
*.so
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# vim
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# Visual Studio build
|
||||
*.ipch
|
||||
.vs/
|
||||
output/
|
||||
include/
|
||||
*.exp
|
||||
*.pdb
|
||||
*.lib
|
||||
*.dll
|
||||
*.exe
|
||||
obj.*
|
||||
*.ipdb
|
||||
*.iobj
|
||||
*.tlog
|
||||
*.log
|
||||
*.obj
|
||||
*.user
|
||||
*.recipe
|
||||
/bin.*
|
||||
*.vcxproj.FileListAbsolute.txt
|
||||
*.vcxprojAssemblyReference.cache
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
# Detours Contributor Credits
|
||||
|
||||
The following individuals have helped identify specific bugs and improvements
|
||||
in Detours. The entire Detours community has benefited from their help.
|
||||
|
||||
* Jay Krell: Identified error in DetourFindPayload that caused a
|
||||
incorrect failure when pcbData is NULL. (Build_342)
|
||||
|
||||
* Jay Krell: Identified issue with VirtualSize == 0 files created in
|
||||
NT 3.1 images. (Build_339)
|
||||
|
||||
* Igor Odnovorov: Identified an issue with the placement of the trampoline
|
||||
region when a function is detoured twice and the second
|
||||
trampoline region is outside of the +/- 2GB range of
|
||||
the target. (Build_337)
|
||||
|
||||
* Jay Krell: Identified need for some programs to enumerate the
|
||||
address of IAT entries. (Build_336)
|
||||
|
||||
* Calvin Hsia: Identified need for some program to change the excluded
|
||||
system region. (Build_336)
|
||||
|
||||
* Adam Smith: Identified error in failure handling when VirtualProect
|
||||
cannot make pages executable because the Prohibit
|
||||
Dynamic Code Generation mitigation policy has been
|
||||
applied to a process. (Build_335)
|
||||
|
||||
* Ben Faull: Identified fix to detour_alloc_region_from_lo and
|
||||
detour_alloc_region_from_hi that preserves ASLR entropy.
|
||||
(Build_334)
|
||||
|
||||
* Shaoxiang Su: Reported errors building with Visual Studio 2015.
|
||||
(Build_332)
|
||||
|
||||
* Jay Krell: Identified and resolved significant gaps in the X86, X64
|
||||
and IA64 disassemblers for instruction found in code,
|
||||
but seldom found in function prologues. (Build_331)
|
||||
|
||||
* Allan Murphy: Identify error in rep and jmp ds: encodings. (Build_331)
|
||||
|
||||
* Philip Bacon: Identified incorrect entry point return for pure
|
||||
resource-only binaries. (Build_330)
|
||||
|
||||
* Jay Krell: Identified failure in DetourAttachEx to update nAlign.
|
||||
(Build_330)
|
||||
|
||||
* Sumit Sarin: Helped debug error with packed binaries.
|
||||
(Build_329)
|
||||
|
||||
* Nitya Kumar Sharma: Reported bug in DetourAfterWithDll for 32/64 agnostic
|
||||
EXEs.
|
||||
(Build_327)
|
||||
|
||||
* Richard Black: Identified a large number of typos in documentation.
|
||||
(Build_326)
|
||||
|
||||
* Michael Bilodeau: Identified bug in DetourUpdateProcessWithDll when the
|
||||
target process contains a Detours payload *after* all
|
||||
valid PE binaries.
|
||||
(Build_324)
|
||||
|
||||
* Meera Jindal: Reported bug in identification of target address in
|
||||
DetourCopyInstruction for jmp[] and call[] on x86 & x64,
|
||||
the ff15 and ff25 opcodes.
|
||||
(Build_323)
|
||||
|
||||
* Ken Johnson: Assistance with SAL 2.0 annotations.
|
||||
(Build_319)
|
||||
|
||||
* Nick Wood: Identified bug in DetourFindFunction on ARM.
|
||||
(Build_314)
|
||||
|
||||
* Mark Russinovich: Helped debug DetourCreateProcessWithDllEx.
|
||||
(Build_314)
|
||||
|
||||
* John Lin: Implementation idea for DetoursCreateProcessWithDllEx.
|
||||
(Build_314)
|
||||
|
||||
* Andrew Zawadowskiy Reported an improper memory page permissions
|
||||
vulnerability in Detours 2.1. (Vulnerability does not
|
||||
exist in versions later than Detours 2.1.)
|
||||
(Build_223)
|
||||
|
||||
* Nightxie: Identified bug in detour_alloc_round_up_to_region.
|
||||
(Build_310)
|
||||
|
||||
* Diana Milirud: Identified bug in B* instructions on ARM.
|
||||
(Build_309)
|
||||
|
||||
* Juan Carlos Identified correct MSIL entry point for unsigned MSIL.
|
||||
Luciani: (Build_308)
|
||||
|
||||
* Lee Hunt Suggested improvements in algorithm for allocation of
|
||||
Lawrence Landauer trampoline regions on x64 to avoid collisions with
|
||||
Joe Laughlin: system DLLs.
|
||||
(Build_307)
|
||||
|
||||
* Tyler Sims Identified bug in handling of "anycpu" MSIL binaries
|
||||
Darren Kennedy: on x64.
|
||||
(Build_307)
|
||||
|
||||
* Andre Vachon: Help with optimized binaries.
|
||||
(Build 301)
|
||||
|
||||
* Chris Mann: Identified fix not forward ported from 2.2 to 3.0.
|
||||
(Build_301)
|
||||
|
||||
* Mark Irving: Identified bug with EXEs missing second import table.
|
||||
(Build_300)
|
||||
|
||||
* Ben Schwarz: Identified bug in handling of multi-byte NOPs.
|
||||
(Build_300)
|
||||
|
||||
* Aaron Giles Coded initial ARM/Thumb2 disassembler.
|
||||
Jared Henderson: (Build_300)
|
||||
|
||||
* Doug Brubacher: Coded initial x86 disassembler.
|
||||
(Build_100)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Copyright (c) Microsoft Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
# MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
ROOT = .
|
||||
!include "$(ROOT)\system.mak"
|
||||
|
||||
all:
|
||||
cd "$(MAKEDIR)"
|
||||
@if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\src"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\samples"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\tests"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
@if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)"
|
||||
|
||||
clean:
|
||||
cd "$(MAKEDIR)"
|
||||
@if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\src"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\samples"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tests"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
@if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)"
|
||||
|
||||
realclean: clean
|
||||
cd "$(MAKEDIR)"
|
||||
@if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\src"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\samples"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tests"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
@if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)"
|
||||
-rmdir /q /s $(INCDS) 2> nul
|
||||
-rmdir /q /s $(LIBDS) 2> nul
|
||||
-rmdir /q /s $(BINDS) 2> nul
|
||||
-rmdir /q /s dist 2> nul
|
||||
-del docsrc\detours.chm 2> nul
|
||||
-del /q *.msi 2>nul
|
||||
-del /q /f /s *~ 2>nul
|
||||
|
||||
test:
|
||||
cd "$(MAKEDIR)\samples"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\tests"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)"
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
# Microsoft Research Detours Package
|
||||
|
||||
Detours is a software package for monitoring and instrumenting API calls on Windows. Detours
|
||||
has been used by many ISVs and is also used by product teams at Microsoft. Detours is now available under
|
||||
a standard open source license ([MIT](https://github.com/microsoft/Detours/blob/master/LICENSE.md)). This simplifies licensing for programmers using Detours
|
||||
and allows the community to support Detours using open source tools and processes.
|
||||
|
||||
Detours is compatible with the Windows NT family of
|
||||
operating systems: Windows NT, Windows XP, Windows Server 2003, Windows 7,
|
||||
Windows 8, and Windows 10. It cannot be used by Windows Store apps
|
||||
because Detours requires APIs not available to those applications.
|
||||
This repo contains the source code for version 4.0.1 of Detours.
|
||||
|
||||
For technical documentation on Detours, see the [Detours Wiki](https://github.com/microsoft/Detours/wiki).
|
||||
For directions on how to build and run samples, see the
|
||||
samples [README.txt](https://github.com/Microsoft/Detours/blob/master/samples/README.TXT) file.
|
||||
|
||||
## Contributing
|
||||
|
||||
The [`Detours`](https://github.com/microsoft/detours) repository is where development is done.
|
||||
Here are some ways you can participate in the project:
|
||||
|
||||
* [Answer questions](https://github.com/microsoft/detours/issues) about using Detours.
|
||||
* [Improve the Wiki](https://github.com/microsoft/detours/wiki).
|
||||
* [Submit bugs](https://github.com/microsoft/detours/issues) and help us verify fixes and changes as they are checked in.
|
||||
* Review [source code changes](https://github.com/microsoft/detours/pulls).
|
||||
|
||||
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
|
||||
you have the right to, and actually do, grant us the rights to use your contribution.
|
||||
For details, visit https://cla.opensource.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
## Issues, questions, and feedback
|
||||
|
||||
* Open an issue on [GitHub Issues](https://github.com/Microsoft/detours/issues).
|
||||
|
||||
## Mailing list for announcements
|
||||
|
||||
The detours-announce mailing list is a low-traffic email list for important announcements
|
||||
about the project, such as the availability of new versions of Detours. To join it, send
|
||||
an email to listserv@lists.research.microsoft.com with a
|
||||
message body containing only the text SUBSCRIBE DETOURS-ANNOUNCE.
|
||||
To leave it, send an email to listserv@lists.research.microsoft.com with a
|
||||
message body containing only the text UNSUBSCRIBE DETOURS-ANNOUNCE.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Licensed under the [MIT](LICENSE.md) License.
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
## Note:
|
||||
## syelog, setdll, and withdll must be built first because a number of the
|
||||
## other samples depend on them.
|
||||
##
|
||||
|
||||
ROOT=..
|
||||
!include .\common.mak
|
||||
|
||||
##############################################################################
|
||||
|
||||
all:
|
||||
cd "$(MAKEDIR)\syelog"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\simple"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\simple_safe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\slept"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\setdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\withdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\cping"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\disas"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\dtest"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\dumpe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\dumpi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\echo"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\einst"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!ENDIF
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
|
||||
cd "$(MAKEDIR)\excep"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!ENDIF
|
||||
cd "$(MAKEDIR)\comeasy"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\commem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\findfunc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!ENDIF
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM" && "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\member"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!ENDIF
|
||||
cd "$(MAKEDIR)\region"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X64" || "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
|
||||
cd "$(MAKEDIR)\talloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!ENDIF
|
||||
cd "$(MAKEDIR)\traceapi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\tracebld"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\tracemem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\tracereg"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\traceser"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\tracessl"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\tracetcp"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\tracelnk"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM" && "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\tryman"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
!ENDIF
|
||||
cd "$(MAKEDIR)\impmunge"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\dynamic_alloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)\payload"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS)
|
||||
cd "$(MAKEDIR)"
|
||||
|
||||
clean:
|
||||
cd "$(MAKEDIR)\syelog"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\simple"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\simple_safe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\slept"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\setdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\withdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\cping"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\disas"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\dtest"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\dumpe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\dumpi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\echo"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\einst"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\excep"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\comeasy"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\commem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\findfunc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\member"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\region"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\talloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\traceapi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tracebld"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tracemem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tracereg"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\traceser"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tracessl"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tracetcp"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tracelnk"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\tryman"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\impmunge"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\dynamic_alloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)\payload"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) clean
|
||||
cd "$(MAKEDIR)"
|
||||
-rmdir lib32 2>nul
|
||||
-rmdir lib64 2>nul
|
||||
-rmdir include 2>nul
|
||||
|
||||
realclean:
|
||||
cd "$(MAKEDIR)\syelog"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\simple"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\simple_safe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\slept"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\setdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\withdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\cping"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\disas"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\dtest"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\dumpe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\dumpi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\echo"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\einst"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\excep"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\comeasy"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\commem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\findfunc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\member"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\region"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\talloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\traceapi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tracebld"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tracemem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tracereg"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\traceser"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tracessl"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tracetcp"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tracelnk"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\tryman"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\impmunge"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\dynamic_alloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)\payload"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean
|
||||
cd "$(MAKEDIR)"
|
||||
-rmdir lib32 2>nul
|
||||
-rmdir lib64 2>nul
|
||||
-rmdir include 2>nul
|
||||
|
||||
test:
|
||||
cd "$(MAKEDIR)\syelog"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\simple"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\simple_safe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\slept"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\setdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\withdll"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
|
||||
cd "$(MAKEDIR)\cping"
|
||||
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
cd "$(MAKEDIR)\disas"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\dtest"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
cd "$(MAKEDIR)\dumpe"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\dumpi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\echo"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\einst"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
|
||||
cd "$(MAKEDIR)\excep"
|
||||
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\comeasy"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
|
||||
cd "$(MAKEDIR)\commem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\findfunc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\member"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\region"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X64" || "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
|
||||
cd "$(MAKEDIR)\talloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\traceapi"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\tracebld"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\tracemem"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\tracereg"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\traceser"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
# cd "$(MAKEDIR)\tracessl"
|
||||
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
# cd "$(MAKEDIR)\tracetcp"
|
||||
# @$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
cd "$(MAKEDIR)\tracelnk"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
!ENDIF
|
||||
cd "$(MAKEDIR)\impmunge"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\dynamic_alloc"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)\payload"
|
||||
@$(MAKE) /NOLOGO /$(MAKEFLAGS) test
|
||||
cd "$(MAKEDIR)"
|
||||
|
||||
##
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Samples README File
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
This README file describes how to set up your build environment, build
|
||||
samples, and run tests.
|
||||
|
||||
BUILD ENVIRONMENT:
|
||||
==================
|
||||
We assume that you have a version of the Visual Studio IDE installed. You can
|
||||
download a free copy of the Visual Studio IDE from
|
||||
https://visualstudio.microsoft.com. During Visual Studio installation, make
|
||||
sure that C/C++ tools are installed and that the Windows SDK is installed.
|
||||
|
||||
Clone the Detours git repo to a directory on your machine. Choose a directory
|
||||
that does not have spaces in the full path name.
|
||||
|
||||
BUILDING:
|
||||
=========
|
||||
Open a Developer Command Prompt for VS. Note there are several different
|
||||
flavors of the command prompt for different target architectures. The
|
||||
default Visual Studio Command prompt targets x86. To target x64, choose
|
||||
the "X64 Native Tools Command Prompt for VS"
|
||||
|
||||
Change directory to the samples directory for your git repo. To build the
|
||||
samples, type "nmake".
|
||||
|
||||
Note that you must build setdll and syslog in order to use many of the
|
||||
other sample programs.
|
||||
|
||||
INSTALLING AND BUILDING VIA VCPKG:
|
||||
==================================
|
||||
You can download and install detours using the vcpkg(https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
vcpkg install detours
|
||||
|
||||
The detours port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request(https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
TESTING:
|
||||
========
|
||||
Each of the sample directories has a test, which can be invoked by typing
|
||||
"nmake test", to demonstrate the usage of the sample. With very few
|
||||
exceptions, all of the executables also accept a "/?" command to display a
|
||||
usage message.
|
||||
|
||||
To run all sample tests, change directory to the samples directory and type
|
||||
"nmake test". Note that some samples are architecture-specific. Tests for
|
||||
those samples be run only on supported architectures and will be skipped on
|
||||
other architectures.
|
||||
|
||||
COMMENTS:
|
||||
=========
|
||||
The trace* samples log their output through the syelogd.exe daemon and hook
|
||||
CreateProcessW to load themselves into any child processes. For example,
|
||||
typing "withdll -d:traceapi.dll cmd.exe" will create a command shell under
|
||||
which all processes log their API calls through traceapi.dll.
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
##############################################################################
|
||||
##
|
||||
## API Extension to Measure time slept.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\wrotei$(DETOURS_BITS).dll \
|
||||
$(BIND)\comeasy.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\wrotei$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\comeasy.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del $(BIND)\wrotei*.* 2>nul
|
||||
-del $(BIND)\comeasy.* 2>nul
|
||||
-del $(BIND)\wrotei.* *~ 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
##############################################################################
|
||||
|
||||
$(OBJD)\wrotei.obj : wrotei.cpp
|
||||
|
||||
$(OBJD)\wrotei.res : wrotei.rc
|
||||
|
||||
$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\wrotei$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\wrotei.obj $(OBJD)\wrotei.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\wrotei.obj $(OBJD)\wrotei.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
$(LIBS) ole32.lib
|
||||
|
||||
$(OBJD)\wrotei$(DETOURS_BITS).bsc : $(OBJD)\wrotei.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\wrotei.sbr
|
||||
|
||||
$(OBJD)\comeasy.obj : comeasy.cpp
|
||||
|
||||
$(BIND)\comeasy.exe : $(OBJD)\comeasy.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
|
||||
$(OBJD)\comeasy.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) ole32.lib \
|
||||
/subsystem:console /fixed:no
|
||||
|
||||
$(OBJD)\comeasy.bsc : $(OBJD)\comeasy.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\comeasy.sbr
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\wrotei$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\wrotei$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).dll : $(OPTD)\wrotei$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).pdb : $(OPTD)\wrotei$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\wrotei$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
|
||||
$(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Adding wrotei$(DETOURS_BITS).dll to comeasy.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should load wrotei$(DETOURS_BITS).dll ----------------------------------------
|
||||
$(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Removing wrotei$(DETOURS_BITS).dll from comeasy.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should not load wrotei$(DETOURS_BITS).dll ------------------------------------
|
||||
$(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Should load wrotei$(DETOURS_BITS).dll dynamically using withdll.exe ----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\wrotei$(DETOURS_BITS).dll $(BIND)\comeasy.exe
|
||||
@echo.
|
||||
@echo -------- Test completed. ------------------------------------------------
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (comeasy.cpp of comeasy.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <ole2.h>
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int __cdecl main(int argc, char **argv)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
LPSTREAM pStream = NULL;
|
||||
ULARGE_INTEGER ul;
|
||||
LARGE_INTEGER li;
|
||||
|
||||
printf("comeasy.exe: Starting (at %p).\n", main);
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
|
||||
ul.QuadPart = 512;
|
||||
hr = pStream->SetSize(ul);
|
||||
|
||||
li.QuadPart = 0;
|
||||
hr = pStream->Seek(li, STREAM_SEEK_SET, NULL);
|
||||
|
||||
printf("comeasy.exe: First write.\n");
|
||||
fflush(stdout);
|
||||
|
||||
li.QuadPart = 0;
|
||||
hr = pStream->Write(&ul, sizeof(ul), NULL);
|
||||
|
||||
printf("comeasy.exe: Second write.\n");
|
||||
fflush(stdout);
|
||||
|
||||
li.QuadPart = 1;
|
||||
hr = pStream->Write(&li, sizeof(li), NULL);
|
||||
|
||||
printf("comeasy.exe: Third write.\n");
|
||||
fflush(stdout);
|
||||
|
||||
li.QuadPart = 2;
|
||||
hr = pStream->Write(&li, sizeof(li), NULL);
|
||||
|
||||
pStream->Release();
|
||||
pStream = NULL;
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
printf("comeasy.exe: Exiting.\n\n");
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (wrotei.cpp of wrotei.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// An example dynamically detouring a function.
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WARNING:
|
||||
//
|
||||
// CINTERFACE must be defined so that the lpVtbl pointer is visible
|
||||
// on COM interfaces. However, once we've defined it, we must use
|
||||
// coding conventions when accessing interface members, for example:
|
||||
// i->lpVtbl->Write
|
||||
// instead of the C++ syntax:
|
||||
// i->Write.
|
||||
// We must also pass the implicit "this" parameter explicitly:
|
||||
// i->lpVtbl->Write(i, pb, 0, NULL)
|
||||
// instead of the C++ syntax:
|
||||
// i->Write(pb, 0, NULL)
|
||||
//
|
||||
#define CINTERFACE
|
||||
#include <ole2.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
LONG dwWrote = 0;
|
||||
|
||||
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
|
||||
static int (WINAPI * RawEntryPoint)(VOID) = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten) = NULL;
|
||||
|
||||
HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
HRESULT hr;
|
||||
ULONG cbWritten = 0;
|
||||
if (pcbWritten == NULL) {
|
||||
pcbWritten = &cbWritten;
|
||||
}
|
||||
|
||||
hr = RealIStreamWrite(This, pv, cb, pcbWritten);
|
||||
|
||||
for (;;) {
|
||||
LONG dwOld = dwWrote;
|
||||
LONG dwNew = dwOld + *pcbWritten;
|
||||
|
||||
if (InterlockedCompareExchange(&dwWrote, dwNew, dwOld) == dwOld) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int WINAPI TimedEntryPoint(VOID)
|
||||
{
|
||||
// We couldn't call CoInitializeEx in DllMain,
|
||||
// so we detour the vtable entries here...
|
||||
LONG error;
|
||||
LPSTREAM pStream = NULL;
|
||||
|
||||
// Create a temporary object so we can get a vtable.
|
||||
CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
|
||||
// Apply the detour to the vtable.
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
if (pStream != NULL) {
|
||||
RealIStreamWrite = pStream->lpVtbl->Write;
|
||||
DetourAttach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
|
||||
}
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (pStream != NULL) {
|
||||
pStream->lpVtbl->Release(pStream);
|
||||
pStream = NULL;
|
||||
}
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured IStream::Wrote() from OnHGlobal.\n");
|
||||
}
|
||||
else {
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring IStram::Wrote(): %ld\n", error);
|
||||
}
|
||||
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Calling EntryPoint\n\n");
|
||||
fflush(stdout);
|
||||
|
||||
return TrueEntryPoint();
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
// NB: DllMain can't call LoadLibrary, so we hook the app entry point.
|
||||
TrueEntryPoint = (int (WINAPI *)(VOID))DetourGetEntryPoint(NULL);
|
||||
RawEntryPoint = TrueEntryPoint;
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured EntryPoint().\n");
|
||||
}
|
||||
else {
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring EntryPoint(): %ld\n", error);
|
||||
}
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
if (RealIStreamWrite != NULL) {
|
||||
DetourDetach(&(PVOID&)RealIStreamWrite, (PVOID)MineIStreamWrite);
|
||||
}
|
||||
DetourDetach(&(PVOID&)TrueEntryPoint, TimedEntryPoint);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Removed IStream::Wrote() detours (%ld), wrote %ld bytes.\n",
|
||||
error, dwWrote);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for wrotei.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "wrotei" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "wrotei" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours COM Easy Sample"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\commem.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\commem.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ *.obj *.sbr 2> nul
|
||||
-del $(BIND)\commem.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(BIND)\commem.obj : commem.cpp
|
||||
|
||||
$(BIND)\commem.exe : $(OBJD)\commem.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\commem.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) ole32.lib /subsystem:console
|
||||
|
||||
$(OBJD)\commem.bsc : $(OBJD)\commem.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\commem.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\commem.exe
|
||||
@echo.
|
||||
$(BIND)\commem.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour functions of a COM interface (commem.cpp of commem.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WARNING:
|
||||
//
|
||||
// CINTERFACE must be defined so that the lpVtbl pointer is visible
|
||||
// on COM interfaces. However, once we've defined it, we must use
|
||||
// coding conventions when accessing interface members, for example:
|
||||
// i->lpVtbl->Write
|
||||
// instead of the C++ syntax:
|
||||
// i->Write.
|
||||
// We must also pass the implicit "this" parameter explicitly:
|
||||
// i->lpVtbl->Write(i, pb, 0, NULL)
|
||||
// instead of the C++ syntax:
|
||||
// i->Write(pb, 0, NULL)
|
||||
//
|
||||
#define CINTERFACE
|
||||
#include <ole2.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
HRESULT (STDMETHODCALLTYPE *RealIStreamWrite)(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten) = NULL;
|
||||
|
||||
HRESULT STDMETHODCALLTYPE MineIStreamWrite(IStream * This,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
HRESULT hr;
|
||||
ULONG cbWritten = 0;
|
||||
if (pcbWritten == NULL) {
|
||||
pcbWritten = &cbWritten;
|
||||
}
|
||||
|
||||
printf("commem: %p->IStreamWrite(pv=%p, cb=%ld)\n", This, pv, cb);
|
||||
hr = RealIStreamWrite(This, pv, cb, pcbWritten);
|
||||
printf("commem: %p->IStreamWrite -> %08lx (pcbWritten=%ld)\n", This, hr, *pcbWritten);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
LPSTREAM pStream = NULL;
|
||||
ULARGE_INTEGER ul;
|
||||
LARGE_INTEGER li;
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
|
||||
RealIStreamWrite = pStream->lpVtbl->Write;
|
||||
|
||||
ul.QuadPart = 512;
|
||||
hr = pStream->lpVtbl->SetSize(pStream, ul);
|
||||
li.QuadPart = 0;
|
||||
hr = pStream->lpVtbl->Seek(pStream, li, STREAM_SEEK_SET, NULL);
|
||||
|
||||
printf("commem: Calling Write w/o before attach.\n");
|
||||
|
||||
li.QuadPart = 0;
|
||||
hr = pStream->lpVtbl->Write(pStream, &ul, sizeof(ul), NULL);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
|
||||
DetourTransactionCommit();
|
||||
|
||||
printf("commem: Calling Write w/o after attach.\n");
|
||||
|
||||
li.QuadPart = 1;
|
||||
hr = pStream->lpVtbl->Write(pStream, &li, sizeof(li), NULL);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)RealIStreamWrite, MineIStreamWrite);
|
||||
DetourTransactionCommit();
|
||||
|
||||
printf("commem: Calling Write w/o after detach.\n");
|
||||
|
||||
li.QuadPart = 2;
|
||||
hr = pStream->lpVtbl->Write(pStream, &li, sizeof(li), NULL);
|
||||
|
||||
hr = pStream->lpVtbl->Release(pStream);
|
||||
pStream = NULL;
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Common makefile for Detours test programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!IF "$(ROOT)" == ""
|
||||
ROOT = ..\..
|
||||
!ENDIF
|
||||
!include "$(ROOT)\system.mak"
|
||||
|
||||
!IF "$(DETOURS_SOURCE_BROWSING)" == ""
|
||||
DETOURS_SOURCE_BROWSING=0
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
!IFNDEF CLIB
|
||||
CLIB=/MT
|
||||
!ENDIF
|
||||
|
||||
AFLAGS=/nologo /Zi /c /Fl
|
||||
CFLAGS=/nologo /Zi $(CLIB) /Gm- /W4 /WX /we4777 /we4800 /Od /DDETOUR_DEBUG=$(DETOURS_DEBUG)
|
||||
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
CFLAGS=$(CFLAGS) /FR
|
||||
!ELSE
|
||||
CFLAGS=$(CFLAGS) /I$(INCD)
|
||||
!ENDIF
|
||||
|
||||
LIBFLAGS=/nologo
|
||||
LINKFLAGS=/release /incremental:no /profile /nodefaultlib:oldnames.lib
|
||||
|
||||
!if defined(DETOURS_WIN_7) && defined(DETOURS_CL_17_OR_NEWER)
|
||||
CFLAGS=$(CFLAGS) /D_USING_V110_SDK71_
|
||||
!endif
|
||||
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
|
||||
|
||||
ASM=ml
|
||||
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
|
||||
|
||||
ASM=ml64
|
||||
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
|
||||
|
||||
ASM=ias
|
||||
AFLAGS=-F COFF32_PLUS
|
||||
CFLAGS=$(CFLAGS) /wd4163 # intrinsic rdtebex not available; using newer Windows headers with older compiler
|
||||
#CFLAGS=$(CFLAGS) /wd4996 /wd4068
|
||||
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
|
||||
|
||||
ASM=armasm
|
||||
AFLAGS=-coff_thumb2_only
|
||||
CFLAGS=$(CFLAGS) /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
|
||||
|
||||
CFLAGS=$(CFLAGS) /D_$(DETOURS_TARGET_PROCESSOR:X64=AMD64)_ # redundant with windows.h except for midl proxies
|
||||
|
||||
!ENDIF
|
||||
|
||||
DEPS = $(LIBD)\syelog.lib $(LIBD)\detours.lib
|
||||
LIBS = $(DEPS)
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
|
||||
.SUFFIXES: .cpp .h .obj .rc .res
|
||||
|
||||
!ifdef DETOURS_ANALYZE
|
||||
.cpp{$(OBJD)}.obj:
|
||||
$(CC) $(CFLAGS) /Fd$(OBJD)\vc.pdb /Fo$(OBJD)\ /c $<
|
||||
!else
|
||||
.cpp{$(OBJD)}.obj::
|
||||
$(CC) $(CFLAGS) /Fd$(OBJD)\vc.pdb /Fo$(OBJD)\ /c $<
|
||||
!endif
|
||||
|
||||
.rc{$(OBJD)}.res:
|
||||
rc /nologo /DDETOURS_BITS=$(DETOURS_BITS) /fo$(@) /i$(INCD) $(*B).rc
|
||||
|
||||
##
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) \
|
||||
kernel32.lib \
|
||||
user32.lib \
|
||||
shell32.lib \
|
||||
uuid.lib \
|
||||
ole32.lib \
|
||||
rpcrt4.lib \
|
||||
advapi32.lib \
|
||||
wsock32.lib \
|
||||
|
||||
# RpcProxy.h uses #ifdef WIN32.
|
||||
|
||||
!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
|
||||
CFLAGS = $(CFLAGS) /D_WIN32_WINNT=0x0500
|
||||
!else
|
||||
CFLAGS = $(CFLAGS) /D_WIN32_WINNT=0x0400
|
||||
!endif
|
||||
|
||||
CFLAGS = $(CFLAGS) /Fd$(OBJD)\vc.pdb \
|
||||
/DCONST_VTABLE \
|
||||
/DCOBJMACROS -DWIN32 -DNT
|
||||
|
||||
C__FLAGS=-DENTRY_PREFIX=iping_ -DREGISTER_PROXY_DLL
|
||||
CPPFLAGS=
|
||||
|
||||
##############################################################################
|
||||
|
||||
.SUFFIXES: .c .cpp .h .idl .obj .res .rc
|
||||
|
||||
{$(OBJD)}.c{$(OBJD)}.obj:
|
||||
$(CC) $(CFLAGS:/W4=/W3) $(C__FLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
|
||||
|
||||
!ifdef DETOURS_ANALYZE
|
||||
.cpp{$(OBJD)}.obj:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
|
||||
!else
|
||||
.cpp{$(OBJD)}.obj::
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) /I$(OBJD) /Fo$(OBJD)\ /c $<
|
||||
!endif
|
||||
|
||||
.rc{$(OBJD)}.res:
|
||||
rc /nologo /Fo$@ .\$(*B).rc
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
C__FLAGS=-DENTRY_PREFIX=iping_ -DREGISTER_PROXY_DLL
|
||||
CPPFLAGS=
|
||||
|
||||
|
||||
MIDLFLAGS=/nologo /Oif /no_format_opt
|
||||
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /no_robust /win32
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /ia64
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /x64
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /arm32
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
|
||||
MIDLFLAGS=$(MIDLFLAGS) /arm64
|
||||
!ENDIF
|
||||
|
||||
OBJS = \
|
||||
$(OBJD)\cping.obj \
|
||||
\
|
||||
$(OBJD)\iping_i.obj \
|
||||
$(OBJD)\iping_p.obj \
|
||||
$(OBJD)\iping_d.obj \
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\cping.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\cping.bsc
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del iping.h *.c *.obj *.sbr *~ 2>nul
|
||||
-del $(BIND)\cping.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\cping.bsc : $(OBJS)
|
||||
bscmake /v /n /o $@ $(OBJS:.obj=.sbr)
|
||||
|
||||
$(BIND)\cping.exe : $(OBJS) $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ $(OBJS) /link $(LINKFLAGS) \
|
||||
/subsystem:console $(LIBS)
|
||||
|
||||
$(OBJD)\cping.obj: cping.cpp $(OBJD)\iping.h
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
$(OBJD)\iping.h $(OBJD)\iping_d.c $(OBJD)\iping_i.c $(OBJD)\iping_p.c : iping.idl
|
||||
midl $(MIDLFLAGS) /out $(OBJD) /prefix all iping_ /dlldata iping_d.c iping.idl
|
||||
|
||||
$(OBJD)\iping_i.obj: $(OBJD)\iping_i.c
|
||||
$(OBJD)\iping_p.obj: $(OBJD)\iping_p.c $(OBJD)\iping.h
|
||||
$(OBJD)\iping_d.obj: $(OBJD)\iping_d.c
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\cping.exe
|
||||
start $(BIND)\cping.exe /s
|
||||
$(BIND)\cping.exe /p localhost
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
Microsoft Research Detours Package
|
||||
==============================================================================
|
||||
4/2/98
|
||||
|
||||
* Instrumentation:
|
||||
Read Pentium cycle counter
|
||||
|
||||
* PC configuration:
|
||||
DCOM/TCP, Windows NT Server 4.0,
|
||||
between two 300MHz Pentium boxes,
|
||||
Ethernet connecction
|
||||
|
||||
* Client test program:
|
||||
HRESULT get(SHORT, SHORT, LONG*)
|
||||
average over 1,000 calls
|
||||
midl /Oicf
|
||||
|
||||
* Results:
|
||||
get() {
|
||||
<-- (1)
|
||||
IRpcChannelBuffer::SendReceive()) {
|
||||
<-- (2)
|
||||
I_RpcSendReceive() {
|
||||
<-- (3)
|
||||
send(soc, )
|
||||
<-- (4)
|
||||
NtWaitForSingleObject(soc, )
|
||||
<-- (5)
|
||||
} // end of RPC layer
|
||||
<-- (6)
|
||||
} // end of channel object
|
||||
<-- (7)
|
||||
} // end of client call
|
||||
Average number
|
||||
of Pentium cycles
|
||||
(1) NDR marshaling overhead (2 SHORTs) 13 K
|
||||
(No! of which 11K from GetBuffer,
|
||||
of which 6.2K from I_RpcGetBuffer()!)
|
||||
(2) Channel object one-way (send) overhead 1.0 K
|
||||
(3) RPC layer one-way (send) overhead 5.3 K
|
||||
(4) TCP + all server work 200 K
|
||||
(5) RPC layer one-way (recv) overhead 5.1 K
|
||||
(6) Channel object one-way (recv) overhead 2.2 K
|
||||
(7) NDR unmarshaling overhead (2 LONGs) 4.2 K
|
||||
|
||||
(*) send() only 17 K
|
||||
TOTAL CYCLES for client get(): 230 K
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,23 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module: iping.idl (cping.exe - COM Ping)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
import "objidl.idl";
|
||||
import "oaidl.idl";
|
||||
import "oleidl.idl";
|
||||
|
||||
|
||||
[object, uuid(decdbeef-d1ac-11d1-96bc-00aa00573fb0), pointer_default(unique)]
|
||||
interface IPing : IUnknown
|
||||
{
|
||||
HRESULT Ping(void);
|
||||
HRESULT PingToServer([in] LPSTR pszString);
|
||||
HRESULT PingToClient([out] LPSTR *ppszString);
|
||||
HRESULT PingToClientSize([in] ULONG cbOut);
|
||||
};
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
# temporarily disable this test for ARM64
|
||||
!if "$(DETOURS_TARGET_PROCESSOR)" != "ARM64"
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\disas.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\disas.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ *.obj *.sbr *.lst 2>nul
|
||||
-del $(BIND)\disas.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86"
|
||||
$(OBJD)\disasm.obj : x86.cpp
|
||||
cl $(CFLAGS) /Fe$@ /FAcs /Fa$(OBJD)\x86.lst \
|
||||
/Fd$(@R).pdb /Fo$(OBJD)\disasm.obj /c x86.cpp
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
|
||||
$(OBJD)\disasm.obj : x64.asm
|
||||
$(ASM) $(AFLAGS) /Fo$(OBJD)\disasm.obj /Fl$(OBJD)\x64.lst x64.asm
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64"
|
||||
$(OBJD)\disasm.obj : ia64.asm
|
||||
$(ASM) $(AFLAGS) -o $(OBJD)\disasm.obj ia64.asm
|
||||
!ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM"
|
||||
$(OBJD)\disasm.obj : arm.asm
|
||||
$(ASM) $(AFLAGS) -list $(OBJD)\arm.lst -o $(OBJD)\disasm.obj arm.asm
|
||||
!ENDIF
|
||||
|
||||
$(BIND)\disas.obj : disas.cpp
|
||||
|
||||
$(BIND)\disas.exe : $(OBJD)\disas.obj $(OBJD)\disasm.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /FAcs /Fa$(OBJD)\disas.lst /Fd$(@R).pdb \
|
||||
$(OBJD)\disas.obj $(OBJD)\disasm.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console /entry:WinMainCRTStartup
|
||||
|
||||
$(OBJD)\disas.bsc : $(OBJD)\disas.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\disas.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\disas.exe
|
||||
$(BIND)\disas.exe
|
||||
|
||||
##############################################################################
|
||||
|
||||
!else
|
||||
|
||||
all:
|
||||
test:
|
||||
clean:
|
||||
realclean:
|
||||
|
||||
!endif
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Detours Test Program (rlo.asm/disas.exe)
|
||||
;;
|
||||
;; Microsoft Research Detours Package
|
||||
;;
|
||||
;; Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
;;
|
||||
|
||||
MACRO
|
||||
BREAK
|
||||
DCW 0xdefe
|
||||
MEND
|
||||
|
||||
AREA |.text|,ALIGN=2,CODE,READONLY
|
||||
|
||||
AREA |.text|,CODE,READONLY
|
||||
|
||||
ALIGN 0x1000
|
||||
|
||||
EXPORT |TestCodes|
|
||||
|TestCodes|
|
||||
|
||||
; dcw 0xf8df,0xe00e ; 94 = -16 = -12 ; 94 ; 98 + e = a6
|
||||
; BREAK ; 98 = -14 = -10 ; 98 ; 9c
|
||||
; dcw 0xf8df,0xe00a ; 9a = -12 = -8 ; 98 ; 9c + a = a6
|
||||
; BREAK ; 9e = -8 = -4 ; 9c ; a0
|
||||
; dcw 0xf8df,0xe002 ; a0 = -6 = -2 ; a0 ; a4 + 2 = a6
|
||||
; BREAK ; a4 = -2 ; a4 ; a8
|
||||
; movs r2, r0 ; a6 <===
|
||||
; movs r3, r0 ;
|
||||
; BREAK
|
||||
; BREAK
|
||||
;
|
||||
; ldr lr,=0xa98765
|
||||
; ldr pc,=0xa98765
|
||||
; ldr pc,=0xa98765
|
||||
; ldr pc,=0xa98765
|
||||
; BREAK
|
||||
; BREAK
|
||||
|
||||
BREAK
|
||||
ldr lr, =0xa98765
|
||||
BREAK
|
||||
blx lr
|
||||
|
||||
BREAK
|
||||
pop pc
|
||||
BREAK
|
||||
pop {r11,pc}
|
||||
BREAK
|
||||
pop {r10,r11,pc}
|
||||
BREAK
|
||||
pop {r9,r10,r11,pc}
|
||||
BREAK
|
||||
pop {r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,pc}
|
||||
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
nop
|
||||
ldr.w r0,=0xa98765
|
||||
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
BREAK
|
||||
ldr.w r0,=0xa98765
|
||||
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
nop
|
||||
nop
|
||||
ldr r0,=0xa98765
|
||||
|
||||
BREAK
|
||||
nop
|
||||
ldr r0,=0xa
|
||||
BREAK
|
||||
ldr r0,=0xa9
|
||||
BREAK
|
||||
ldr r0,=0xa98
|
||||
BREAK
|
||||
ldr r0,=0xa987
|
||||
BREAK
|
||||
ldr r0,=0xa9876
|
||||
BREAK
|
||||
ldr r0,=0xa98765
|
||||
BREAK
|
||||
ldr r0,=0xa987654
|
||||
BREAK
|
||||
ldr r0,=0xa9876543
|
||||
|
||||
;; Simple instructions.
|
||||
BREAK
|
||||
adds r0,r0, #5 ; 1d40
|
||||
BREAK
|
||||
movs r2, #0 ; 2200
|
||||
BREAK
|
||||
movs r3, #0 ; 2300
|
||||
BREAK
|
||||
bx lr ; 4770 [FFFFFFFF]
|
||||
|
||||
;; Known 16-bit instructions
|
||||
BREAK
|
||||
mov r11, sp ; 46eb
|
||||
BREAK
|
||||
movs r2, r0 ; 0002
|
||||
BREAK
|
||||
push r0, r1 ; b403
|
||||
BREAK
|
||||
str r3,[r7,#0x28] ; 62bb
|
||||
BREAK
|
||||
bx r5 ; 4728 [FFFFFFFF]
|
||||
BREAK
|
||||
blx r5 ; 47a8
|
||||
BREAK
|
||||
DCW 0x4878 ; ldr r0, [PC + 0x1E0] ; 4878
|
||||
BREAK
|
||||
str r3,[r7,#0x1C] ; 61fb
|
||||
BREAK
|
||||
ldr r3,[r7,#0x38] ; 6bbb
|
||||
BREAK
|
||||
add r3,sp,#0xCC ; ab33
|
||||
BREAK
|
||||
cbz r2,+0x56 ; b34a [00xx1510]
|
||||
BREAK
|
||||
cbnz r2,+0x56 ; bb4a [00xx1514]
|
||||
BREAK
|
||||
push {r0,r2,r4,r6,lr} ; b555
|
||||
BREAK
|
||||
nop ; bf00
|
||||
|
||||
;; Placeholder for IT instruction
|
||||
BREAK
|
||||
bne +0x6E ; d135 [00xx1538] -??? d137
|
||||
BREAK
|
||||
svc #0x24 ; df24
|
||||
BREAK
|
||||
b +0x7FE ; e3fd [00xx1cd0] -??? e3ff
|
||||
|
||||
;; 32 bit test codes
|
||||
BREAK
|
||||
adds r0,r7,#8 ; f1170008
|
||||
BREAK
|
||||
str r3,[r5,#0x677] ; f8c53677
|
||||
BREAK
|
||||
ldrsh r10,[r5,#0x5A5] ; f9b5a5a5
|
||||
BREAK
|
||||
DCW 0xf89f,0x55a5 ;ldrb r5, [+0x5A5] ; f89f55a5
|
||||
BREAK
|
||||
bls.w +0x86; 0xf240; 0x8043; // ; f2408041 [00xx157A]
|
||||
BREAK
|
||||
bl +0xFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFFFE; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFFF0; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
bl +0xFFFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
DCW 0xf7ff,0xff80
|
||||
;bl +0xFFFFFF00; 0xf7ff; 0xff80; //
|
||||
BREAK
|
||||
DCW 0xf7ff,0xbe02
|
||||
; b.w ; 0xf7ff; 0xbe02; // (10053528)
|
||||
BREAK
|
||||
push {r7,r11,lr}; 0xe92d; 0x4880; //
|
||||
|
||||
;; 32 bit expected results
|
||||
BREAK
|
||||
adds r0,r7,#8 ; 0xf1170008
|
||||
BREAK
|
||||
str r3,[r5,#0x677] ; 0xf8c53677
|
||||
BREAK
|
||||
ldrsh r10,[r5,#0x5A5] ; 0xf9b5a5a5
|
||||
|
||||
BREAK
|
||||
DCW 0xf6af,0xfbd2
|
||||
; bl (0008ef3c); ResultCode(4, 0xf6af, 0xfbd2, Target(ADDRESS(&g_pTestCodes32[i*2], 0xFFFFFF00))); // 0xf7ff, 0xff80: -> 0xf6affbd2
|
||||
BREAK
|
||||
bl (00090300); ResultCode(4, 0xf6af, 0xba54, Target(ADDRESS(&g_pTestCodes32[i*2], 0xFFFFFC04))); // 0xf7ff, 0xff80: -> f6afba54 bl (00090300)
|
||||
BREAK
|
||||
push {r7,r11,lr}; ResultCode(4, 0xe92d, 0x4880); // 0xe92d, 0x4880: //
|
||||
|
||||
BREAK
|
||||
BREAK
|
||||
|
||||
|TestCodes_end|
|
||||
|
||||
END
|
||||
|
|
@ -0,0 +1,702 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module: disas.cpp (disas.exe - Detours Test Program)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#define DETOURS_INTERNAL
|
||||
#include <detours.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////// ARM.
|
||||
//
|
||||
#ifdef DETOURS_ARM
|
||||
|
||||
extern "C" BYTE TestCodes[];
|
||||
|
||||
void DumpMemoryFragment(PBYTE pbData, ULONG cbData, ULONG cbSpace)
|
||||
{
|
||||
ULONG n = 0;
|
||||
if (cbData >= 4) {
|
||||
printf("%04x%04x ", ((PUSHORT)pbData)[0], ((PUSHORT)pbData)[1]);
|
||||
n += 4;
|
||||
}
|
||||
else if (cbData >= 2) {
|
||||
printf("%04x ", *((PUSHORT)pbData));
|
||||
n += 2;
|
||||
}
|
||||
|
||||
for (; n < cbSpace; n++) {
|
||||
if (n < cbData) {
|
||||
printf("%02x", pbData[n]);
|
||||
}
|
||||
else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
if (n < cbData) {
|
||||
printf(".");
|
||||
}
|
||||
else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
inline ULONG fetch_thumb_opcode(PBYTE pbCode)
|
||||
{
|
||||
ULONG Opcode = *(UINT16 *)&pbCode[0];
|
||||
if (Opcode >= 0xe800) {
|
||||
Opcode = (Opcode << 16) | *(UINT16 *)&pbCode[2];
|
||||
}
|
||||
return Opcode;
|
||||
}
|
||||
|
||||
BOOL IsTerminate(PBYTE pbSrc)
|
||||
{
|
||||
ULONG opcode = fetch_thumb_opcode(pbSrc);
|
||||
|
||||
if ((opcode & 0xff87) == 0x4700) {
|
||||
// bx r
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ((opcode & 0xfbf08f00) == 0xf2400c00) { // movw r12,#xxxx
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((opcode == 0xf8dcf000) { // ldr pc,[r12]
|
||||
ULONG Immediate = ((opcode2 << 12) & 0xf7000000) |
|
||||
((opcode2 << 1) & 0x08000000) |
|
||||
((opcode2 << 16) & 0x00ff0000) |
|
||||
((opcode >> 4) & 0x0000f700) |
|
||||
((opcode >> 15) & 0x00000800) |
|
||||
((opcode >> 0) & 0x000000ff);
|
||||
PBYTE pbTarget = *(PBYTE *)Immediate;
|
||||
if (detour_is_imported(pbCode, pbTarget)) {
|
||||
PBYTE pbNew = *(PBYTE *)pbTarget;
|
||||
DETOUR_TRACE(("%p->%p: skipped over import table.\n", pbCode, pbNew));
|
||||
return pbNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif // DETOURS_ARM
|
||||
|
||||
///////////////////////////////////////////////////////////////// X86 and X64.
|
||||
//
|
||||
#if defined(DETOURS_X86) || defined(DETOURS_X64)
|
||||
|
||||
extern "C" BYTE TestCodes[];
|
||||
|
||||
void DumpMemoryFragment(PBYTE pbData, ULONG cbData, ULONG cbSpace)
|
||||
{
|
||||
ULONG n = 0;
|
||||
for (; n < cbSpace; n++) {
|
||||
if (n < cbData) {
|
||||
printf("%02x", pbData[n]);
|
||||
}
|
||||
else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
if (n < cbData) {
|
||||
printf(".");
|
||||
}
|
||||
else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
BOOL IsTerminate(PBYTE pbSrc)
|
||||
{
|
||||
if ((0xC3 == pbSrc[0] && 0x00 == pbSrc[1]) || // bx lr
|
||||
0xCB == pbSrc[0] || // RETF
|
||||
0xC2 == pbSrc[0] || // RET dw
|
||||
0xCA == pbSrc[0] || // RETF dw
|
||||
0xEB == pbSrc[0] || // JMP ob
|
||||
0xE9 == pbSrc[0] || // JMP ol
|
||||
0xEA == pbSrc[0]) { // JMP ol
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
if (0xff == pbSrc[0] && 0x25 == pbSrc[1]) // JMP [addr]
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif // DETOURS_X86 || DETOURS_X64
|
||||
|
||||
/////////////////////////////////////////////////////////// X86, X64, and ARM.
|
||||
//
|
||||
#if defined(DETOURS_X86) || defined(DETOURS_X64) || defined(DETOURS_ARM)
|
||||
struct BasicBlockLink
|
||||
{
|
||||
public:
|
||||
BasicBlockLink * m_pNext;
|
||||
PBYTE m_pbEntry;
|
||||
PCHAR m_pszName;
|
||||
|
||||
public:
|
||||
BasicBlockLink(PBYTE pbEntry, PCHAR pszName = NULL)
|
||||
{
|
||||
m_pNext = NULL;
|
||||
m_pbEntry = pbEntry;
|
||||
m_pszName = pszName;
|
||||
|
||||
*s_ppTail = this;
|
||||
s_ppTail = &m_pNext;
|
||||
}
|
||||
|
||||
BasicBlockLink * Next()
|
||||
{
|
||||
return m_pNext;
|
||||
}
|
||||
|
||||
static BasicBlockLink * GetListHead()
|
||||
{
|
||||
return s_pHead;
|
||||
}
|
||||
|
||||
protected:
|
||||
static BasicBlockLink * s_pHead;
|
||||
static BasicBlockLink ** s_ppTail;
|
||||
};
|
||||
|
||||
BasicBlockLink * BasicBlockLink::s_pHead = NULL;
|
||||
BasicBlockLink ** BasicBlockLink::s_ppTail = &BasicBlockLink::s_pHead;
|
||||
|
||||
static PBYTE s_pbBegin = NULL;
|
||||
static PBYTE s_pbLimit = NULL;
|
||||
|
||||
int TestDetourCopyInstruction(PBYTE pbSrcInstruction, PCHAR pszFunction)
|
||||
{
|
||||
PBYTE pbSrc = pbSrcInstruction;
|
||||
ULONG nIns = 0;
|
||||
|
||||
if (pszFunction) {
|
||||
printf("%s:\n", pszFunction);
|
||||
}
|
||||
for (; nIns < 4096; nIns++) {
|
||||
BYTE rbDst[128];
|
||||
PVOID pbDstPool = (PVOID)(rbDst + sizeof(rbDst));
|
||||
LONG lExtra = 0;
|
||||
PVOID pbTarget = NULL;
|
||||
ULONG cbStep = (ULONG)((PBYTE)DetourCopyInstruction(rbDst, &pbDstPool, pbSrc,
|
||||
&pbTarget, &lExtra) - pbSrc);
|
||||
|
||||
printf(" %p:", pbSrc);
|
||||
DumpMemoryFragment(rbDst, cbStep, 10);
|
||||
printf(" ");
|
||||
DumpMemoryFragment(rbDst, cbStep, 10);
|
||||
if (pbTarget) {
|
||||
if (pbTarget == DETOUR_INSTRUCTION_TARGET_DYNAMIC) {
|
||||
printf(" Dynamic\n");
|
||||
}
|
||||
else {
|
||||
printf(" %p%c\n", pbTarget,
|
||||
(pbTarget >= s_pbBegin && pbTarget < s_pbLimit) ? ' ' : '!');
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (pbTarget && pbTarget != DETOUR_INSTRUCTION_TARGET_DYNAMIC) {
|
||||
if (pbTarget > pbSrc &&
|
||||
pbTarget >= s_pbBegin &&
|
||||
pbTarget < s_pbLimit
|
||||
) {
|
||||
(void) new BasicBlockLink((PBYTE)pbTarget, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsTerminate(pbSrc)) {
|
||||
break;
|
||||
}
|
||||
|
||||
pbSrc += cbStep;
|
||||
}
|
||||
return nIns;
|
||||
}
|
||||
|
||||
BOOL CALLBACK ExportCallback(_In_opt_ PVOID pContext,
|
||||
_In_ ULONG nOrdinal,
|
||||
_In_opt_ LPCSTR pszName,
|
||||
_In_opt_ PVOID pCode)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)nOrdinal;
|
||||
(void)pCode;
|
||||
|
||||
(VOID) new BasicBlockLink((PBYTE)pCode, pszName ? pszName : "[NO NAME]");
|
||||
return TRUE;
|
||||
}
|
||||
#endif // DETOURS_X86 || DETOURS_X64
|
||||
|
||||
//////////////////////////////////////////////////////////////////////// IA64.
|
||||
//
|
||||
#ifdef DETOURS_IA64
|
||||
#pragma warning(disable: 4201) // ignore warning about unnamed sturcture in union.
|
||||
|
||||
void DumpHi(PBYTE pbData, ULONG cbData, ULONG cbSpace)
|
||||
{
|
||||
ULONG n = 0;
|
||||
for (; n < cbSpace; n++) {
|
||||
if (n < cbData) {
|
||||
printf("%02x", pbData[(cbData - 1) - n]);
|
||||
}
|
||||
else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
struct DETOUR_IA64_BUNDLE_DISASSEMBLE : public DETOUR_IA64_BUNDLE
|
||||
{
|
||||
public:
|
||||
void SetBrx(UINT64 raw)
|
||||
{
|
||||
SetBrl();
|
||||
SetBrlImm(raw);
|
||||
}
|
||||
|
||||
void Dis()
|
||||
{
|
||||
const char szUnitNames[17] = "?aimbflx?AIMBFLX";
|
||||
|
||||
printf("%p: ", data);
|
||||
BYTE nTemplate = GetTemplate();
|
||||
BYTE nInst0 = GetInst0();
|
||||
BYTE nInst1 = GetInst1();
|
||||
BYTE nInst2 = GetInst2();
|
||||
BYTE nUnit0 = GetUnit0();
|
||||
BYTE nUnit1 = GetUnit1();
|
||||
BYTE nUnit2 = GetUnit2();
|
||||
if (nUnit1 == L_UNIT) { // MLX instruction
|
||||
UINT64 d2 = (
|
||||
// 0x0000000000fffff0
|
||||
((wide[1] & 0x00fffff000000000) >> 32) |
|
||||
// 0x000000ffff000000
|
||||
((wide[0] & 0xffff000000000000) >> 24) |
|
||||
// 0x7fffff0000000000
|
||||
((wide[1] & 0x00000000007fffff) << 40) |
|
||||
// 0x8000000000000000
|
||||
((wide[1] & 0x0800000000000000) << 4)
|
||||
);
|
||||
printf("%02x %c%01x %010I64lx %c%01x %016I64lx",
|
||||
nTemplate,
|
||||
szUnitNames[nUnit0], nInst0, GetData0(),
|
||||
szUnitNames[nUnit2], nInst2, d2);
|
||||
}
|
||||
else {
|
||||
printf("%02x %c%01x %010I64lx %c%01x %010I64lx %c%01x %010I64lx",
|
||||
nTemplate,
|
||||
szUnitNames[nUnit0], nInst0, GetData0(),
|
||||
szUnitNames[nUnit1], nInst1, GetData1(),
|
||||
szUnitNames[nUnit2], nInst2, GetData2());
|
||||
}
|
||||
|
||||
if (IsBrl()) {
|
||||
printf(" brl %p", GetBrlTarget());
|
||||
}
|
||||
else if (IsMovlGp()) {
|
||||
printf(" movl gp=%p", GetMovlGp());
|
||||
}
|
||||
if ((wide[0] & 0xfffffc000603ffff) == 0x002024000200100b &&
|
||||
wide[1] == 0x0004000000203008) {
|
||||
|
||||
ULONG64 offset =
|
||||
((wide[0] & 0x0000000001fc0000) >> 18) | // imm7b
|
||||
((wide[0] & 0x000001ff00000000) >> 25) | // imm9d
|
||||
((wide[0] & 0x00000000f8000000) >> 11); // imm5c
|
||||
if (wide[0] & 0x0000020000000000) {
|
||||
offset |= 0xffffffffffe00000;
|
||||
}
|
||||
printf(" imm=%016I64lx", offset);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
BOOL CALLBACK ExportCallbackIA64(_In_opt_ PVOID pContext,
|
||||
_In_ ULONG nOrdinal,
|
||||
_In_opt_ LPCSTR pszName,
|
||||
_In_opt_ PVOID pCode)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)nOrdinal;
|
||||
|
||||
DETOUR_IA64_BUNDLE_DISASSEMBLE *pb = *(DETOUR_IA64_BUNDLE_DISASSEMBLE **)pCode;
|
||||
DETOUR_IA64_BUNDLE temp;
|
||||
|
||||
if (!pb[0].Copy(&temp)) {
|
||||
printf("%s:\n ", pszName ? pszName : "[NO NAME]");
|
||||
pb[0].Dis();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void TestBoth()
|
||||
{
|
||||
LPVOID pvBase = VirtualAlloc((PBYTE)0x800000000, 0x10000,
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_EXECUTE_READWRITE);
|
||||
|
||||
DETOUR_IA64_BUNDLE *pbBase = (DETOUR_IA64_BUNDLE *)pvBase;
|
||||
DETOUR_IA64_BUNDLE *pb = pbBase;
|
||||
|
||||
printf("TestBoth:\n");
|
||||
for (UINT64 i = 0x10; i < 0x8000000000000000; i <<= 1) {
|
||||
pb->SetMovlGp(i);
|
||||
if (pb->GetMovlGp() != i) {
|
||||
printf("Error in MovlGp!\n");
|
||||
return;
|
||||
}
|
||||
pb++;
|
||||
|
||||
pb->SetBrl(i);
|
||||
if (pb->GetBrlEip() != i) {
|
||||
printf("Error in Brl!\n");
|
||||
return;
|
||||
}
|
||||
pb++;
|
||||
}
|
||||
|
||||
for (UINT64 i = (UINT64)(INT64)-0x10; i > 0; i <<= 1) {
|
||||
pb->SetMovlGp(i);
|
||||
if (pb->GetMovlGp() != i) {
|
||||
printf("Error in MovlGp!\n");
|
||||
return;
|
||||
}
|
||||
pb++;
|
||||
|
||||
pb->SetBrl(i);
|
||||
if (pb->GetBrlEip() != i) {
|
||||
printf("Error in Brl!\n");
|
||||
return;
|
||||
}
|
||||
pb++;
|
||||
}
|
||||
|
||||
printf("u %p %p\n", pbBase, pb);
|
||||
}
|
||||
#endif
|
||||
#endif // DETOURS_IA64
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
(void)hprev;
|
||||
(void)hinst;
|
||||
(void)lpszCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
// Bug report, but it works here.
|
||||
// 07ff8`4b783054 49ba 70b3d93a d40fb998 mov r10,98B90FD43AD9B370h
|
||||
//
|
||||
{
|
||||
static const UCHAR mov_r10_imm64[] = {0x49, 0xba, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
|
||||
PVOID const after = DetourCopyInstructionX64(0, 0, const_cast<PUCHAR>(mov_r10_imm64), 0, 0);
|
||||
|
||||
if (after != &mov_r10_imm64 + 1)
|
||||
{
|
||||
printf("mov_r10_imm64 failed, expected:%p vs. got:%p\n", &mov_r10_imm64 + 1, after);
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
__debugbreak();
|
||||
DetourCopyInstructionX64(0, 0, const_cast<PUCHAR>(mov_r10_imm64), 0, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DETOURS_IA64
|
||||
// First we check the pre-canned TestCodes from disasm.asm
|
||||
//
|
||||
PBYTE pbTest = *(PBYTE*)WinMain;
|
||||
for (;; pbTest += 16) {
|
||||
DETOUR_IA64_BUNDLE_DISASSEMBLE *pb = (DETOUR_IA64_BUNDLE_DISASSEMBLE *)pbTest;
|
||||
|
||||
pb->Dis();
|
||||
if (pbTest[0] == 0xff) {
|
||||
break;
|
||||
}
|
||||
DumpHi(pbTest, 16, 16);
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("\n\n");
|
||||
|
||||
DETOUR_IA64_BUNDLE_DISASSEMBLE *pb = (DETOUR_IA64_BUNDLE_DISASSEMBLE *)pbTest;
|
||||
DETOUR_IA64_BUNDLE_DISASSEMBLE *pbBeg = pb;
|
||||
DWORD dwOld;
|
||||
VirtualProtect(pb, 0x2000, PAGE_EXECUTE_READWRITE, &dwOld);
|
||||
printf("%p: (%d)\n", pb, sizeof(pb));
|
||||
pb++;
|
||||
printf("%p: (%d)\n", pb, sizeof(pb));
|
||||
pb++; pb->SetBrx(0);
|
||||
pb++; pb->SetBrx(0);
|
||||
pb++; pb->SetBrx(0);
|
||||
pb++; pb->SetBrx(0xffffffffffffffff);
|
||||
pb++; pb->SetBrx(0x0fffffffffffffff);
|
||||
pb++; pb->SetBrx(0x00ffffffffffffff);
|
||||
pb++; pb->SetBrx(0x000fffffffffffff);
|
||||
pb++; pb->SetBrx(0x0000ffffffffffff);
|
||||
pb++; pb->SetBrx(0x00000fffffffffff);
|
||||
pb++; pb->SetBrx(0x000000ffffffffff);
|
||||
pb++; pb->SetBrx(0x0000000fffffffff);
|
||||
pb++; pb->SetBrx(0x00000000ffffffff);
|
||||
pb++; pb->SetBrx(0x000000000fffffff);
|
||||
pb++; pb->SetBrx(0x0000000000ffffff);
|
||||
pb++; pb->SetBrx(0x00000000000fffff);
|
||||
pb++; pb->SetBrx(0x000000000000ffff);
|
||||
pb++; pb->SetBrx(0x0000000000000fff);
|
||||
pb++; pb->SetBrx(0x00000000000000ff);
|
||||
pb++; pb->SetBrx(0x000000000000000f);
|
||||
pb++; pb->SetBrx(0x0000000000000000);
|
||||
pb++; pb->SetBrx(0xffffffffffffffff);
|
||||
pb++; pb->SetBrx(0xffffffffffffffff);
|
||||
pb->SetInst0(0xff);
|
||||
pb->SetData0(0xffffffffffffffff);
|
||||
printf("%p:\n", pb);
|
||||
DETOUR_IA64_BUNDLE_DISASSEMBLE *pbEnd = pb;
|
||||
for (pb = pbBeg; pb < pbEnd; pb++) {
|
||||
printf(" %p: ", pb);
|
||||
DumpHi((BYTE*)pb, 16, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
{
|
||||
// Then we check all of the code we can find in user32.dll
|
||||
//
|
||||
printf("\n");
|
||||
HINSTANCE hInst = LoadLibraryA("user32.dll");
|
||||
printf("Loaded: user32.dll: %p\n", hInst);
|
||||
|
||||
PBYTE pbEntry = (PBYTE)DetourGetEntryPoint(hInst);
|
||||
printf("Entry: %p\n", pbEntry);
|
||||
ExportCallbackIA64(NULL, 0, "[Entry]", pbEntry);
|
||||
DetourEnumerateExports(hInst, NULL, ExportCallbackIA64);
|
||||
}
|
||||
|
||||
{
|
||||
// Then we check all of the code we can find in opengl32.dll
|
||||
//
|
||||
printf("\n");
|
||||
HINSTANCE hInst = LoadLibraryA("opengl32.dll");
|
||||
printf("Loaded: opengl32.dll: %p\n", hInst);
|
||||
|
||||
PBYTE pbEntry = (PBYTE)DetourGetEntryPoint(hInst);
|
||||
printf("Entry: %p\n", pbEntry);
|
||||
ExportCallbackIA64(NULL, 0, "[Entry]", pbEntry);
|
||||
DetourEnumerateExports(hInst, NULL, ExportCallbackIA64);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
for (HINSTANCE hInst = NULL; (hInst = DetourEnumerateModules(hInst)) != NULL;) {
|
||||
CHAR szModuleName[512];
|
||||
GetModuleFileNameA(hInst, szModuleName,
|
||||
sizeof(szModuleName)/sizeof(szModuleName[0]));
|
||||
printf("%p : %s\n", hInst, szModuleName);
|
||||
DetourEnumerateExports(hInst, NULL, ExportCallbackIA64);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
#if 0
|
||||
TestBoth();
|
||||
#endif
|
||||
#endif // DETOURS_IA64
|
||||
|
||||
#if defined(DETOURS_X64) || defined(DETOURS_X86)
|
||||
// First we check the pre-canned TestCodes from disasm.asm
|
||||
//
|
||||
PBYTE pbBegin = (PBYTE)DetourCodeFromPointer(TestCodes, NULL);
|
||||
printf("%p:\n", pbBegin);
|
||||
for (PBYTE pbTest = pbBegin;;) {
|
||||
if (pbTest[0] != 0xcc) { // int 3
|
||||
printf("%08lx ", (ULONG)(pbTest - pbBegin));
|
||||
DumpMemoryFragment(pbTest, 8, 8);
|
||||
printf("\n");
|
||||
printf("failed on last.\n");
|
||||
return 1;
|
||||
}
|
||||
pbTest++;
|
||||
|
||||
if (pbTest[0] == 0x70 || pbTest[0] == 0x71) {
|
||||
printf("[%p]:\n", pbTest);
|
||||
}
|
||||
BYTE rbDst[128];
|
||||
PVOID pbDstPool = (PVOID)(rbDst + sizeof(rbDst));
|
||||
LONG lExtra = 0;
|
||||
PVOID pbTarget = NULL;
|
||||
PBYTE pbNext = (PBYTE)DetourCopyInstruction(rbDst, &pbDstPool, pbTest,
|
||||
&pbTarget, &lExtra);
|
||||
|
||||
LONG cbTest = (LONG)(pbNext - pbTest);
|
||||
|
||||
printf("%08lx ", (ULONG)(pbTest - pbBegin));
|
||||
DumpMemoryFragment(pbTest, cbTest, 12);
|
||||
printf("[%16p] ", pbTarget);
|
||||
DumpMemoryFragment(rbDst, cbTest + lExtra, 11);
|
||||
printf("\n");
|
||||
|
||||
if (pbTest[cbTest] != 0xcc) {
|
||||
printf("failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pbTest += cbTest;
|
||||
|
||||
if (pbTest[0] == 0xcc && pbTest[1] == 0xcc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Then we check all of the code we can find in user32.dll
|
||||
//
|
||||
HINSTANCE hInst = LoadLibraryA("user32.dll");
|
||||
printf("Loaded: user32.dll: %p\n", hInst);
|
||||
|
||||
s_pbBegin = (PBYTE)hInst;
|
||||
s_pbLimit = s_pbBegin + DetourGetModuleSize(hInst);
|
||||
|
||||
PBYTE pbEntry = DetourGetEntryPoint(hInst);
|
||||
(VOID) new BasicBlockLink(pbEntry, "user32.dll");
|
||||
|
||||
DetourEnumerateExports(hInst, NULL, ExportCallback);
|
||||
|
||||
ULONG nIns = 0;
|
||||
for (BasicBlockLink *pLink = BasicBlockLink::GetListHead();
|
||||
pLink; pLink = pLink->Next()) {
|
||||
|
||||
nIns += TestDetourCopyInstruction(pLink->m_pbEntry, pLink->m_pszName);
|
||||
if (nIns > 100000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("Disassembled %d instructions.\n", nIns);
|
||||
#endif
|
||||
#endif // DETOURS_X86 || DETOURS_X64
|
||||
|
||||
#ifdef DETOURS_ARM
|
||||
// Create an output buffer and fill it with debugbreaks.
|
||||
//
|
||||
PBYTE pbBuffer
|
||||
= (PBYTE)VirtualAlloc(NULL, 0x400, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
for (PBYTE pbOut = pbBuffer; pbOut < pbBuffer + 0x400;) {
|
||||
*pbOut++ = 0xfe;
|
||||
*pbOut++ = 0xde;
|
||||
}
|
||||
PBYTE pbDst = pbBuffer;
|
||||
PVOID pvDstPool = (PVOID)(pbBuffer + 0x400);
|
||||
|
||||
// First we check the pre-canned TestCodes from disasm.asm
|
||||
//
|
||||
PBYTE pbBegin = (PBYTE)DetourCodeFromPointer(TestCodes, NULL);
|
||||
printf("%p: (TestCodes %p) => %p\n", pbBegin, TestCodes, pbBuffer);
|
||||
for (PBYTE pbSrc = pbBegin;;) {
|
||||
if (pbSrc[0] != 0xfe && pbSrc[1] != 0xde) { // BREAK
|
||||
printf("%08x ", pbSrc - pbBegin);
|
||||
DumpMemoryFragment(pbSrc, 8, 8);
|
||||
printf("\n");
|
||||
printf("failed on last.\n");
|
||||
return 1;
|
||||
}
|
||||
pbSrc += 2;
|
||||
*pbDst++ = 0xfe;
|
||||
*pbDst++ = 0xde;
|
||||
|
||||
if ((pbSrc[0] == 0x00 && pbSrc[1] == 0xbf) && // NOP
|
||||
(pbSrc[2] != 0xfe && pbSrc[3] != 0xde)) { // BREAK
|
||||
// Skip over a single NOP so we can test alignment.
|
||||
pbSrc += 2;
|
||||
}
|
||||
|
||||
if ((pbSrc[0] == 0x00 && pbSrc[1] == 0xbf) && // NOP
|
||||
(pbSrc[2] != 0xfe && pbSrc[3] != 0xde)) { // BREAK
|
||||
// If there is a second NOP, then we insert alignment.
|
||||
pbSrc += 2;
|
||||
*pbDst++ = 0x00;
|
||||
*pbDst++ = 0xbf;
|
||||
}
|
||||
|
||||
|
||||
LONG lExtra = 0;
|
||||
PVOID pbTarget = NULL;
|
||||
PBYTE pbNext = (PBYTE)DetourCopyInstruction(pbDst, &pvDstPool, pbSrc, &pbTarget, &lExtra);
|
||||
|
||||
LONG cbTest = (LONG)(pbNext - pbSrc);
|
||||
|
||||
printf("%08x ", pbSrc - pbBegin);
|
||||
DumpMemoryFragment(pbSrc, cbTest, 4);
|
||||
printf("[%8p] ", pbTarget);
|
||||
DumpMemoryFragment(pbDst, cbTest + lExtra, 16);
|
||||
printf("\n");
|
||||
|
||||
if (pbSrc[cbTest] != 0xfe || pbSrc[cbTest+1] != 0xde) {
|
||||
printf("%p: failed! (pbSrc[n]=%02x, pbSrc[n+1]=%02x\n",
|
||||
pbSrc,
|
||||
pbSrc[cbTest], pbSrc[cbTest+1]);
|
||||
__debugbreak();
|
||||
pbNext = (PBYTE)DetourCopyInstruction(pbDst, &pvDstPool, pbSrc, &pbTarget, &lExtra);
|
||||
cbTest = (LONG)(pbNext - pbSrc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pbDst += cbTest + lExtra;
|
||||
pbSrc += cbTest;
|
||||
|
||||
if (pbSrc[0] == 0xfe && pbSrc[1] == 0xde &&
|
||||
pbSrc[2] == 0xfe && pbSrc[3] == 0xde) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Then we check all of the code we can find in user32.dll
|
||||
//
|
||||
HINSTANCE hInst = LoadLibraryA("user32.dll");
|
||||
printf("Loaded: user32.dll: %p\n", hInst);
|
||||
|
||||
s_pbBegin = (PBYTE)hInst;
|
||||
s_pbLimit = s_pbBegin + DetourGetModuleSize(hInst);
|
||||
|
||||
PBYTE pbEntry = DetourGetEntryPoint(hInst);
|
||||
(VOID) new BasicBlockLink(pbEntry, "user32.dll");
|
||||
|
||||
DetourEnumerateExports(hInst, NULL, ExportCallback);
|
||||
|
||||
ULONG nIns = 0;
|
||||
for (BasicBlockLink *pLink = BasicBlockLink::GetListHead();
|
||||
pLink; pLink = pLink->Next()) {
|
||||
|
||||
nIns += TestDetourCopyInstruction(pLink->m_pbEntry, pLink->m_pszName);
|
||||
if (nIns > 100000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("Disassembled %d instructions.\n", nIns);
|
||||
#endif
|
||||
#endif // DETOURS_ARM
|
||||
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,15 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (x86.asm of disas.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
static int value = 0;
|
||||
|
||||
extern "C" void TestCodes()
|
||||
{
|
||||
value++;
|
||||
}
|
||||
|
|
@ -0,0 +1,520 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Detours Test Program (x64.asm/disas.exe)
|
||||
;;
|
||||
;; Microsoft Research Detours Package
|
||||
;;
|
||||
;; Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
;;
|
||||
|
||||
.xlist
|
||||
.list
|
||||
.code
|
||||
|
||||
PUBLIC TestCodes
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
TestCodes PROC
|
||||
|
||||
begin:
|
||||
faraway:
|
||||
int 3
|
||||
nop
|
||||
int 3
|
||||
db 066h,090h ; // 2-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 000h ; // 3-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 040h, 000h ; // 4-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 044h, 000h, 000h ; // 5-byte NOP.
|
||||
int 3
|
||||
db 066h, 00fh, 01fh, 044h, 000h, 000h ; // 6-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 080h, 000h, 000h, 000h, 000h ; // 7-byte NOP.
|
||||
int 3
|
||||
db 00fh, 01fh, 084h, 000h, 000h, 000h, 000h, 000h ; // 8-byte NOP.
|
||||
int 3
|
||||
db 066h, 00fh, 01fh, 084h, 000h, 000h, 000h, 000h, 000h ; // 9-byte NOP.
|
||||
int 3
|
||||
mov rax, cr8
|
||||
int 3
|
||||
mov rcx, cr8
|
||||
int 3
|
||||
mov rdx, cr8
|
||||
int 3
|
||||
mov rbx, cr8
|
||||
int 3
|
||||
mov rsp, cr8
|
||||
int 3
|
||||
mov rbp, cr8
|
||||
int 3
|
||||
mov rsi, cr8
|
||||
int 3
|
||||
mov rdi, cr8
|
||||
int 3
|
||||
mov r8, cr8
|
||||
int 3
|
||||
mov r9, cr8
|
||||
int 3
|
||||
mov r10, cr8
|
||||
int 3
|
||||
mov r11, cr8
|
||||
int 3
|
||||
mov r12, cr8
|
||||
int 3
|
||||
mov r13, cr8
|
||||
int 3
|
||||
mov r14, cr8
|
||||
int 3
|
||||
mov r15, cr8
|
||||
int 3
|
||||
mov cr8, rax
|
||||
int 3
|
||||
mov cr8, rcx
|
||||
int 3
|
||||
mov cr8, rdx
|
||||
int 3
|
||||
mov cr8, rbx
|
||||
int 3
|
||||
mov cr8, rsp
|
||||
int 3
|
||||
mov cr8, rbp
|
||||
int 3
|
||||
mov cr8, rsi
|
||||
int 3
|
||||
mov cr8, rdi
|
||||
int 3
|
||||
mov cr8, r8
|
||||
int 3
|
||||
mov cr8, r9
|
||||
int 3
|
||||
mov cr8, r10
|
||||
int 3
|
||||
mov cr8, r11
|
||||
int 3
|
||||
mov cr8, r12
|
||||
int 3
|
||||
mov cr8, r13
|
||||
int 3
|
||||
mov cr8, r14
|
||||
int 3
|
||||
mov cr8, r15
|
||||
int 3
|
||||
xor rax, rax
|
||||
int 3
|
||||
xor rcx, rcx
|
||||
int 3
|
||||
xor rdx, rdx
|
||||
int 3
|
||||
xor rbx, rbx
|
||||
int 3
|
||||
xor rsp, rsp
|
||||
int 3
|
||||
xor rbp, rbp
|
||||
int 3
|
||||
xor rsi, rsi
|
||||
int 3
|
||||
xor rdi, rdi
|
||||
int 3
|
||||
xor r8, r8
|
||||
int 3
|
||||
xor r9, r9
|
||||
int 3
|
||||
xor r10, r10
|
||||
int 3
|
||||
xor r11, r11
|
||||
int 3
|
||||
xor r12, r12
|
||||
int 3
|
||||
xor r13, r13
|
||||
int 3
|
||||
xor r14, r14
|
||||
int 3
|
||||
xor r15, r15
|
||||
int 3
|
||||
jmp rax
|
||||
int 3
|
||||
jmp rbx
|
||||
int 3
|
||||
jmp rcx
|
||||
int 3
|
||||
jmp rdx
|
||||
int 3
|
||||
push rax
|
||||
int 3
|
||||
push rbx
|
||||
int 3
|
||||
push rcx
|
||||
int 3
|
||||
push rdx
|
||||
int 3
|
||||
push 0
|
||||
int 3
|
||||
pop rax
|
||||
int 3
|
||||
pop rbx
|
||||
int 3
|
||||
pop rcx
|
||||
int 3
|
||||
pop rdx
|
||||
int 3
|
||||
mov rax,[value]
|
||||
int 3
|
||||
sub rsp,0418h
|
||||
int 3
|
||||
mov [rsp+0410h],rbx
|
||||
int 3
|
||||
mov [rsp+0408h],rsi
|
||||
int 3
|
||||
mov [rsp+0400h],rdi
|
||||
int 3
|
||||
mov [rsp+03f8h],r12
|
||||
int 3
|
||||
mov [rsp+03f0h],r13
|
||||
int 3
|
||||
mov [rsp+03e8h],r14
|
||||
int 3
|
||||
mov [rsp+03e0h],r15
|
||||
int 3
|
||||
add [rax],al ; 0000
|
||||
int 3
|
||||
add [rcx],al ; 0001
|
||||
int 3
|
||||
add [rbx],al ; 0003
|
||||
int 3
|
||||
add [rax+rax],al ; 000400
|
||||
int 3
|
||||
add [rdi],al ; 0007
|
||||
int 3
|
||||
add [rax],cl ; 0008
|
||||
int 3
|
||||
add [rdi],cl ; 000f
|
||||
int 3
|
||||
add [rax],dl ; 0010
|
||||
int 3
|
||||
add [rdi],bl ; 001f
|
||||
int 3
|
||||
add [rax],ah ; 0020
|
||||
int 3
|
||||
add [rdi],bh ; 003f
|
||||
int 3
|
||||
add [rax+03bh],cl ; 00483b
|
||||
int 3
|
||||
add [rdi],bh ; 007f00
|
||||
int 3
|
||||
add [rax+040000000h],al ; 008000000040
|
||||
int 3
|
||||
add bh,bh ; 00ff
|
||||
int 3
|
||||
add [rax],eax ; 0100
|
||||
int 3
|
||||
add al,[rax] ; 0200
|
||||
int 3
|
||||
add eax,06603ebc3h ; 05c3eb0366
|
||||
int 3
|
||||
syscall ; 0f05
|
||||
int 3
|
||||
prefetchw byte ptr [rcx] ; 0f0d09
|
||||
int 3
|
||||
prefetchnta byte ptr [rcx] ; 0f1801
|
||||
int 3
|
||||
prefetchnta byte ptr [rax+rdx] ; 0f180410
|
||||
int 3
|
||||
jb again ; 0f8247070000
|
||||
int 3
|
||||
jnb again ; 0f8306050000
|
||||
int 3
|
||||
je again ; 0f8432010000
|
||||
int 3
|
||||
jne again ; 0f8508010000
|
||||
int 3
|
||||
jnbe again ; 0f878a000000
|
||||
int 3
|
||||
ldmxcsr dword ptr [rcx+034h] ; 0fae5134
|
||||
int 3
|
||||
stmxcsr dword ptr [rcx+034h] ; 0fae5934
|
||||
int 3
|
||||
and ecx,[rdx+rbx*4] ; 230c9a
|
||||
int 3
|
||||
xor eax,eax ; 33c0
|
||||
int 3
|
||||
xor ecx,ecx ; 33c9
|
||||
int 3
|
||||
xor edx,ecx ; 33d1
|
||||
int 3
|
||||
xor edx,edx ; 33d2
|
||||
int 3
|
||||
add r10d,010001h ; 4181c201000100
|
||||
int 3
|
||||
and r11d,0ffffh ; 4181e3ffff0000
|
||||
int 3
|
||||
mov eax,r8d ; 418bc0
|
||||
int 3
|
||||
mov byte ptr [r11],00h ; 41c60300
|
||||
int 3
|
||||
call qword ptr [r9+030h] ; 41ff5130
|
||||
int 3
|
||||
call qword ptr [r9+r8*8] ; 43ff14c1
|
||||
int 3
|
||||
mov [rcx+034h],r8d ; 44894134
|
||||
int 3
|
||||
mov [rsp+030h],r9d ; 44894c2430
|
||||
int 3
|
||||
mov r8d,[rcx] ; 448b01
|
||||
int 3
|
||||
mov r9d,[rcx] ; 448b09
|
||||
int 3
|
||||
mov r8d,[rax+058h] ; 448b4058
|
||||
int 3
|
||||
mov r8d,[rsp+02ch] ; 448b44242c
|
||||
int 3
|
||||
mov r8d,eax ; 448bc0
|
||||
int 3
|
||||
mov r8d,edx ; 448bc2
|
||||
int 3
|
||||
xor r8b,r8b ; 4532c0
|
||||
int 3
|
||||
mov r9d,r8d ; 458bc8
|
||||
int 3
|
||||
lea r11d,[r9+rax] ; 458d1c01
|
||||
int 3
|
||||
add rdx,rcx ; 4803d1
|
||||
int 3
|
||||
or rsi,rdx ; 480bf2
|
||||
int 3
|
||||
movnti [rcx],rax ; 480fc301
|
||||
int 3
|
||||
and rax,0fe000000h ; 4825000000fe
|
||||
int 3
|
||||
sub rax,rcx ; 482bc1
|
||||
int 3
|
||||
sub rdx,rcx ; 482bd1
|
||||
int 3
|
||||
cmp rdi,rbp ; 483bfd
|
||||
int 3
|
||||
push rbp ; 4855
|
||||
int 3
|
||||
add rcx,03d0h ; 4881c1d0030000
|
||||
int 3
|
||||
add rsp,0c8h ; 4881c4c8000000
|
||||
int 3
|
||||
and rdx,0fe000000h ; 4881e2000000fe
|
||||
int 3
|
||||
sub rsp,0c8h ; 4881ecc8000000
|
||||
int 3
|
||||
sub rsp,03d0h ; 4881ecd0030000
|
||||
int 3
|
||||
add rax,040h ; 4883c040
|
||||
int 3
|
||||
add rcx,08h ; 4883c108
|
||||
int 3
|
||||
add rcx,040h ; 4883c140
|
||||
int 3
|
||||
add rsp,08h ; 4883c408
|
||||
int 3
|
||||
add rsi,09h ; 4883c609
|
||||
int 3
|
||||
add rdi,01h ; 4883c701
|
||||
int 3
|
||||
and rcx,0f8h ; 4883e1f8
|
||||
int 3
|
||||
sub rax,040h ; 4883e840
|
||||
int 3
|
||||
sub rdx,08h ; 4883ea08
|
||||
int 3
|
||||
sub rdx,040h ; 4883ea40
|
||||
int 3
|
||||
sub rsp,08h ; 4883ec08
|
||||
int 3
|
||||
sub rsi,08h ; 4883ee08
|
||||
int 3
|
||||
sub rdi,01h ; 4883ef01
|
||||
int 3
|
||||
test rax,rax ; 4885c0
|
||||
int 3
|
||||
test rdx,rdx ; 4885d2
|
||||
int 3
|
||||
mov [rsp],rax ; 48890424
|
||||
int 3
|
||||
mov [rsp],rbp ; 48892c24
|
||||
int 3
|
||||
mov [rsp],rsi ; 48893424
|
||||
int 3
|
||||
mov [rsp],rdi ; 48893c24
|
||||
int 3
|
||||
mov [rcx+08h],rax ; 48894108
|
||||
int 3
|
||||
mov [rcx+078h],rax ; 48894178
|
||||
int 3
|
||||
mov [rcx-08h],rax ; 488941f8
|
||||
int 3
|
||||
mov [rsp+018h],rax ; 4889442418
|
||||
int 3
|
||||
mov [rcx+010h],rdx ; 48895110
|
||||
int 3
|
||||
mov [rsp+08h],rbx ; 48895c2408
|
||||
int 3
|
||||
mov [rsp+018h],rsi ; 4889742418
|
||||
int 3
|
||||
mov [rsp+08h],rdi ; 48897c2408
|
||||
int 3
|
||||
mov [rsp+010h],rdi ; 48897c2410
|
||||
int 3
|
||||
mov [rcx+098h],rax ; 48898198000000
|
||||
int 3
|
||||
mov [rcx+080h],rcx ; 48898980000000
|
||||
int 3
|
||||
mov [rcx+088h],rdx ; 48899188000000
|
||||
int 3
|
||||
mov [rcx+090h],rbx ; 48899990000000
|
||||
int 3
|
||||
mov [rcx+0a0h],rbp ; 4889a9a0000000
|
||||
int 3
|
||||
mov [rcx+0a8h],rsi ; 4889b1a8000000
|
||||
int 3
|
||||
mov [rcx+0b0h],rdi ; 4889b9b0000000
|
||||
int 3
|
||||
mov rax,[rcx] ; 488b01
|
||||
int 3
|
||||
mov rax,[rcx+rdx] ; 488b0411
|
||||
int 3
|
||||
mov rax,[value] ; 488b05318c0100
|
||||
int 3
|
||||
mov rcx,[rsp] ; 488b0c24
|
||||
int 3
|
||||
mov rsi,[rsp] ; 488b3424
|
||||
int 3
|
||||
mov rdi,[rsp] ; 488b3c24
|
||||
int 3
|
||||
mov rax,[rax+018h] ; 488b4018
|
||||
int 3
|
||||
mov rax,[rcx+078h] ; 488b4178
|
||||
int 3
|
||||
mov rax,[rdx+020h] ; 488b4220
|
||||
int 3
|
||||
mov rax,[rsp+08h] ; 488b442408
|
||||
int 3
|
||||
mov rcx,[rcx+08h] ; 488b4908
|
||||
int 3
|
||||
mov rcx,[rsp+020h] ; 488b4c2420
|
||||
int 3
|
||||
mov rdx,[rsp+08h] ; 488b542408
|
||||
int 3
|
||||
mov rdi,[rsp+08h] ; 488b7c2408
|
||||
int 3
|
||||
mov rax,[rcx+098h] ; 488b8198000000
|
||||
int 3
|
||||
mov rax,[rcx+0f8h] ; 488b81f8000000
|
||||
int 3
|
||||
cmp ebx,0 ;
|
||||
int 3
|
||||
cmp rbx,0 ;
|
||||
int 3
|
||||
cmp byte ptr [value],77h ; 803d........77
|
||||
int 3
|
||||
cmp dword ptr [value],77h ; 833d........77
|
||||
int 3
|
||||
cmp qword ptr [value],77h ; 48833d........77
|
||||
int 3
|
||||
cmp dword ptr [value],77777777h ; 813d........77777777
|
||||
int 3
|
||||
cmp qword ptr [value],77777777h ; 48813d........77777777
|
||||
int 3
|
||||
nearby:
|
||||
jo nearby ; 70xx
|
||||
int 3
|
||||
jno nearby ; 71xx
|
||||
int 3
|
||||
jb nearby ; 72xx
|
||||
int 3
|
||||
jae nearby ; 73xx
|
||||
int 3
|
||||
je nearby ; 74xx
|
||||
int 3
|
||||
jne nearby ; 75xx
|
||||
int 3
|
||||
jbe nearby ; 76xx
|
||||
int 3
|
||||
ja nearby ; 77xx
|
||||
int 3
|
||||
js nearby ; 78xx
|
||||
int 3
|
||||
jns nearby ; 79xx
|
||||
int 3
|
||||
jp nearby ; 7axx
|
||||
int 3
|
||||
jnp nearby ; 7bxx
|
||||
int 3
|
||||
jl nearby ; 7cxx
|
||||
int 3
|
||||
jge nearby ; 7dxx
|
||||
int 3
|
||||
jle nearby ; 7exx
|
||||
int 3
|
||||
jg nearby ; 7fxx
|
||||
int 3
|
||||
jmp nearby ; ebxx
|
||||
|
||||
int 3
|
||||
jo faraway ; 0f80xxxxxxxx
|
||||
int 3
|
||||
jno faraway ; 0f81xxxxxxxx
|
||||
int 3
|
||||
jb faraway ; 0f82xxxxxxxx
|
||||
int 3
|
||||
jae faraway ; 0f83xxxxxxxx
|
||||
int 3
|
||||
je faraway ; 0f84xxxxxxxx
|
||||
int 3
|
||||
jne faraway ; 0f85xxxxxxxx
|
||||
int 3
|
||||
jbe faraway ; 0f86xxxxxxxx
|
||||
int 3
|
||||
ja faraway ; 0f87xxxxxxxx
|
||||
int 3
|
||||
js faraway ; 0f88xxxxxxxx
|
||||
int 3
|
||||
jns faraway ; 0f89xxxxxxxx
|
||||
int 3
|
||||
jp faraway ; 0f8axxxxxxxx
|
||||
int 3
|
||||
jnp faraway ; 0f8bxxxxxxxx
|
||||
int 3
|
||||
jl faraway ; 0f8cxxxxxxxx
|
||||
int 3
|
||||
jge faraway ; 0f8dxxxxxxxx
|
||||
int 3
|
||||
jle faraway ; 0f8exxxxxxxx
|
||||
int 3
|
||||
jg faraway ; 0f8fxxxxxxxx
|
||||
int 3
|
||||
jmp faraway ; e9xxxxxxxx
|
||||
|
||||
int 3
|
||||
lea rax,[rsp] ; 488d0424
|
||||
int 3
|
||||
mov rcx,0BADC0DEBA5Eh ; 48b95ebadec0ad0b0000
|
||||
int 3
|
||||
cmp rax,rcx ; 483bc1
|
||||
|
||||
int 3
|
||||
sub rsp, 28h
|
||||
int 3
|
||||
add rsp,28h
|
||||
int 3
|
||||
ret
|
||||
int 3
|
||||
|
||||
|
||||
;; The list is terminated by two "int 3" in a row.
|
||||
again:
|
||||
int 3
|
||||
int 3
|
||||
TestCodes ENDP
|
||||
|
||||
value QWORD 0
|
||||
|
||||
_TEXT ENDS
|
||||
END
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (x86.asm of disas.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
static int value = 0;
|
||||
|
||||
extern "C" void __declspec(naked) TestCodes()
|
||||
{
|
||||
__asm {
|
||||
// Each instruction is proceeded by an "int 3".
|
||||
faraway:
|
||||
int 3;
|
||||
nop; // 1-byte NOP.
|
||||
int 3;
|
||||
_emit 0x66; // 2-byte NOP.
|
||||
_emit 0x90;
|
||||
int 3;
|
||||
_emit 0x0f; // 3-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 4-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x40;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 5-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x44;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x66; // 6-byte NOP.
|
||||
_emit 0x0f;
|
||||
_emit 0x1f;
|
||||
_emit 0x44;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 7-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x80;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x0f; // 8-byte NOP.
|
||||
_emit 0x1f;
|
||||
_emit 0x84;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
_emit 0x66; // 9-byte NOP.
|
||||
_emit 0x0f;
|
||||
_emit 0x1f;
|
||||
_emit 0x84;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
_emit 0x00;
|
||||
int 3;
|
||||
mov ecx, eax;
|
||||
int 3;
|
||||
mov ebx, 0ffff000eh;
|
||||
int 3;
|
||||
call ebx;
|
||||
int 3;
|
||||
call dword ptr [eax];
|
||||
int 3;
|
||||
call dword ptr [ebx];
|
||||
int 3;
|
||||
call dword ptr [ecx];
|
||||
int 3;
|
||||
call dword ptr [edx];
|
||||
int 3;
|
||||
jmp dword ptr [eax];
|
||||
int 3;
|
||||
jmp dword ptr [ebx];
|
||||
int 3;
|
||||
jmp dword ptr [ecx];
|
||||
int 3;
|
||||
jmp dword ptr [edx];
|
||||
int 3;
|
||||
call ecx;
|
||||
int 3;
|
||||
call eax;
|
||||
int 3;
|
||||
mov ebx, 0ffff000eh;
|
||||
int 3;
|
||||
push eax;
|
||||
int 3;
|
||||
call ebx;
|
||||
int 3;
|
||||
cmp ebx, 0;
|
||||
int 3;
|
||||
cmp byte ptr [value], 77h;
|
||||
int 3;
|
||||
cmp dword ptr [value], 77h;
|
||||
int 3;
|
||||
cmp dword ptr [value], 77777777h;
|
||||
nearby:
|
||||
int 3
|
||||
jo nearby ; 70xx
|
||||
int 3
|
||||
jno nearby ; 71xx
|
||||
int 3
|
||||
jb nearby ; 72xx
|
||||
int 3
|
||||
jae nearby ; 73xx
|
||||
int 3
|
||||
je nearby ; 74xx
|
||||
int 3
|
||||
jne nearby ; 75xx
|
||||
int 3
|
||||
jbe nearby ; 76xx
|
||||
int 3
|
||||
ja nearby ; 77xx
|
||||
int 3
|
||||
js nearby ; 78xx
|
||||
int 3
|
||||
jns nearby ; 79xx
|
||||
int 3
|
||||
jp nearby ; 7axx
|
||||
int 3
|
||||
jnp nearby ; 7bxx
|
||||
int 3
|
||||
jl nearby ; 7cxx
|
||||
int 3
|
||||
jge nearby ; 7dxx
|
||||
int 3
|
||||
jle nearby ; 7exx
|
||||
int 3
|
||||
jg nearby ; 7fxx
|
||||
|
||||
int 3
|
||||
jo faraway ; 0f80xx
|
||||
int 3
|
||||
jno faraway ; 0f81xx
|
||||
int 3
|
||||
jb faraway ; 0f82xx
|
||||
int 3
|
||||
jae faraway ; 0f83xx
|
||||
int 3
|
||||
je faraway ; 0f84xx
|
||||
int 3
|
||||
jne faraway ; 0f85xx
|
||||
int 3
|
||||
jbe faraway ; 0f86xx
|
||||
int 3
|
||||
ja faraway ; 0f87xx
|
||||
int 3
|
||||
js faraway ; 0f88xx
|
||||
int 3
|
||||
jns faraway ; 0f89xx
|
||||
int 3
|
||||
jp faraway ; 0f8axx
|
||||
int 3
|
||||
jnp faraway ; 0f8bxx
|
||||
int 3
|
||||
jl faraway ; 0f8cxx
|
||||
int 3
|
||||
jge faraway ; 0f8dxx
|
||||
int 3
|
||||
jle faraway ; 0f8exx
|
||||
int 3
|
||||
jg faraway ; 0f8fxx
|
||||
|
||||
// The list is terminated by two "int 3" in a row.
|
||||
int 3;
|
||||
int 3;
|
||||
ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\dtarge$(DETOURS_BITS).dll \
|
||||
$(BIND)\dtest.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\dtarge$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\dtest.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
clean:
|
||||
-del *~ *.obj *.sbr 2> nul
|
||||
-del $(BIND)\dtest.* $(BIND)\dtarge*.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\dtarge.obj : dtarge.cpp
|
||||
|
||||
$(OBJD)\dtarge.res : dtarge.rc
|
||||
|
||||
$(BIND)\dtarge$(DETOURS_BITS).dll $(BIND)\dtarge$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\dtarge.obj $(OBJD)\dtarge.res $(DEPS)
|
||||
cl /LD $(CFLAGS) \
|
||||
/Fe$(@R).dll \
|
||||
/Fd$(@R).pdb \
|
||||
$(OBJD)\dtarge.obj $(OBJD)\dtarge.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:Target0 \
|
||||
/export:Target1 \
|
||||
/export:Target2 \
|
||||
/export:Target3 \
|
||||
/export:Target4 \
|
||||
/export:Target5 \
|
||||
/export:Target6 \
|
||||
/export:Target7 \
|
||||
/export:Target8 \
|
||||
/export:Target9 \
|
||||
/export:Target10 \
|
||||
/export:Target11 \
|
||||
/export:Target12 \
|
||||
/export:Target13 \
|
||||
/export:Target14 \
|
||||
/export:Target15 \
|
||||
/export:Target16 \
|
||||
/export:TargetV \
|
||||
/export:TargetR \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\dtarge$(DETOURS_BITS).bsc : $(OBJD)\dtarge.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dtarge.sbr
|
||||
|
||||
$(OBJD)\dtest.obj : dtest.cpp
|
||||
|
||||
$(BIND)\dtest.exe : $(OBJD)\dtest.obj $(BIND)\dtarge$(DETOURS_BITS).lib $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dtest.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) $(BIND)\dtarge$(DETOURS_BITS).lib \
|
||||
/subsystem:console /entry:WinMainCRTStartup
|
||||
|
||||
$(OBJD)\dtest.bsc : $(OBJD)\dtest.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dtest.sbr
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\dtarge$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\dtarge$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).dll : $(OPTD)\dtarge$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).pdb : $(OPTD)\dtarge$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\dtarge$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
$(BIND)\dtest.exe
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
..\..\bin.IA64\dtest.exe
|
||||
Calling LocalTarget1 w/o detour
|
||||
LocalTarget1 (1)
|
||||
Calling LocalTarget1 w/ detour
|
||||
MyLocalTarget1 (2)
|
||||
LocalTarget1 (2)
|
||||
Calling Target0 function.
|
||||
MyTarget0 ()
|
||||
Calling TargetN functions.
|
||||
MyLocalTarget1 (1)
|
||||
LocalTarget1 (1)
|
||||
MyTarget0 ()
|
||||
MyTarget1 (1)
|
||||
MyTarget2 (1,2)
|
||||
MyTarget3 (1,2,3)
|
||||
MyTarget4 (1,2,3,4)
|
||||
MyTarget5 (1,2,3,4,5)
|
||||
MyTarget6 (1,2,3,4,5,6)
|
||||
MyTarget7 (1,2,3,4,5,6,7)
|
||||
MyTarget8 (1,2,3,4,5,6,7,8)
|
||||
MyTarget9 (1,2,3,4,5,6,7,8,9)
|
||||
MyTarget10(1,2,3,4,5,6,7,8,9,10)
|
||||
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetV (0)
|
||||
MyTargetV (0,1)
|
||||
MyTargetV (0,1,2)
|
||||
MyTargetV (0,1,2,3)
|
||||
MyTargetV (0,1,2,3,4)
|
||||
MyTargetV (0,1,2,3,4,5)
|
||||
MyTargetV (0,1,2,3,4,5,6)
|
||||
MyTargetV (0,1,2,3,4,5,6,7)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetR (0,1,2,3,4)
|
||||
MyTargetR (0,1,2,3,3)
|
||||
MyTargetR (0,1,2,3,2)
|
||||
MyTargetR (0,1,2,3,1)
|
||||
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
=> 3011
|
||||
Calling Target0 again with 1 detour.
|
||||
MyTarget0 ()
|
||||
Calling Target0 again with 2 detours.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
Calling Target0 again with 3 detours.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
Calling Target0 again with 4 detours.
|
||||
Starting Target0_3.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
End Target0_3.
|
||||
Done.
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target1 (1)
|
||||
Target2 (1,2)
|
||||
Target3 (1,2,3)
|
||||
Target4 (1,2,3,4)
|
||||
Target5 (1,2,3,4,5)
|
||||
Target6 (1,2,3,4,5,6)
|
||||
Target7 (1,2,3,4,5,6,7)
|
||||
Target8 (1,2,3,4,5,6,7,8)
|
||||
Target9 (1,2,3,4,5,6,7,8,9)
|
||||
Target10(1,2,3,4,5,6,7,8,9,10)
|
||||
Target11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
TargetV (0)
|
||||
TargetV (0,1)
|
||||
TargetV (0,1,2)
|
||||
TargetV (0,1,2,3)
|
||||
TargetV (0,1,2,3,4)
|
||||
TargetV (0,1,2,3,4,5)
|
||||
TargetV (0,1,2,3,4,5,6)
|
||||
TargetV (0,1,2,3,4,5,6,7)
|
||||
TargetV (0,1,2,3,4,5,6,7,8)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
::: TargetR (0,1,2,3,1)
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
..\..\bin.X64\dtest.exe
|
||||
Calling LocalTarget1 w/o detour
|
||||
LocalTarget1 (1)
|
||||
Calling LocalTarget1 w/ detour
|
||||
MyLocalTarget1 (2)
|
||||
LocalTarget1 (2)
|
||||
Calling Target0 function.
|
||||
MyTarget0 ()
|
||||
Calling TargetN functions.
|
||||
MyLocalTarget1 (1)
|
||||
LocalTarget1 (1)
|
||||
MyTarget0 ()
|
||||
MyTarget1 (1)
|
||||
MyTarget2 (1,2)
|
||||
MyTarget3 (1,2,3)
|
||||
MyTarget4 (1,2,3,4)
|
||||
MyTarget5 (1,2,3,4,5)
|
||||
MyTarget6 (1,2,3,4,5,6)
|
||||
MyTarget7 (1,2,3,4,5,6,7)
|
||||
MyTarget8 (1,2,3,4,5,6,7,8)
|
||||
MyTarget9 (1,2,3,4,5,6,7,8,9)
|
||||
MyTarget10(1,2,3,4,5,6,7,8,9,10)
|
||||
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetV (0)
|
||||
MyTargetV (0,1)
|
||||
MyTargetV (0,1,2)
|
||||
MyTargetV (0,1,2,3)
|
||||
MyTargetV (0,1,2,3,4)
|
||||
MyTargetV (0,1,2,3,4,5)
|
||||
MyTargetV (0,1,2,3,4,5,6)
|
||||
MyTargetV (0,1,2,3,4,5,6,7)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetR (0,1,2,3,4)
|
||||
MyTargetR (0,1,2,3,3)
|
||||
MyTargetR (0,1,2,3,2)
|
||||
MyTargetR (0,1,2,3,1)
|
||||
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
=> 3011
|
||||
Calling Target0 again with 1 detour.
|
||||
MyTarget0 ()
|
||||
Calling Target0 again with 2 detours.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
Calling Target0 again with 3 detours.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
Calling Target0 again with 4 detours.
|
||||
Starting Target0_3.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
End Target0_3.
|
||||
Done.
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target1 (1)
|
||||
Target2 (1,2)
|
||||
Target3 (1,2,3)
|
||||
Target4 (1,2,3,4)
|
||||
Target5 (1,2,3,4,5)
|
||||
Target6 (1,2,3,4,5,6)
|
||||
Target7 (1,2,3,4,5,6,7)
|
||||
Target8 (1,2,3,4,5,6,7,8)
|
||||
Target9 (1,2,3,4,5,6,7,8,9)
|
||||
Target10(1,2,3,4,5,6,7,8,9,10)
|
||||
Target11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
TargetV (0)
|
||||
TargetV (0,1)
|
||||
TargetV (0,1,2)
|
||||
TargetV (0,1,2,3)
|
||||
TargetV (0,1,2,3,4)
|
||||
TargetV (0,1,2,3,4,5)
|
||||
TargetV (0,1,2,3,4,5,6)
|
||||
TargetV (0,1,2,3,4,5,6,7)
|
||||
TargetV (0,1,2,3,4,5,6,7,8)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
::: TargetR (0,1,2,3,1)
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
..\..\bin.X86\dtest.exe
|
||||
Calling LocalTarget1 w/o detour
|
||||
LocalTarget1 (1)
|
||||
Calling LocalTarget1 w/ detour
|
||||
MyLocalTarget1 (2)
|
||||
LocalTarget1 (2)
|
||||
Calling Target0 function.
|
||||
MyTarget0 ()
|
||||
Calling TargetN functions.
|
||||
MyLocalTarget1 (1)
|
||||
LocalTarget1 (1)
|
||||
MyTarget0 ()
|
||||
MyTarget1 (1)
|
||||
MyTarget2 (1,2)
|
||||
MyTarget3 (1,2,3)
|
||||
MyTarget4 (1,2,3,4)
|
||||
MyTarget5 (1,2,3,4,5)
|
||||
MyTarget6 (1,2,3,4,5,6)
|
||||
MyTarget7 (1,2,3,4,5,6,7)
|
||||
MyTarget8 (1,2,3,4,5,6,7,8)
|
||||
MyTarget9 (1,2,3,4,5,6,7,8,9)
|
||||
MyTarget10(1,2,3,4,5,6,7,8,9,10)
|
||||
MyTarget11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTarget12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTarget13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTarget14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTarget15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTarget16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetV (0)
|
||||
MyTargetV (0,1)
|
||||
MyTargetV (0,1,2)
|
||||
MyTargetV (0,1,2,3)
|
||||
MyTargetV (0,1,2,3,4)
|
||||
MyTargetV (0,1,2,3,4,5)
|
||||
MyTargetV (0,1,2,3,4,5,6)
|
||||
MyTargetV (0,1,2,3,4,5,6,7)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
MyTargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
MyTargetR (0,1,2,3,4)
|
||||
MyTargetR (0,1,2,3,3)
|
||||
MyTargetR (0,1,2,3,2)
|
||||
MyTargetR (0,1,2,3,1)
|
||||
.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... MyTargetR (0,1,2,3,4,5,6,7,8,9,10,4)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,3)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,2)
|
||||
MyTargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
=> 3011
|
||||
Calling Target0 again with 1 detour.
|
||||
MyTarget0 ()
|
||||
Calling Target0 again with 2 detours.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
Calling Target0 again with 3 detours.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
Calling Target0 again with 4 detours.
|
||||
Starting Target0_3.
|
||||
Starting Target0_2.
|
||||
Starting Target0_1.
|
||||
MyTarget0 ()
|
||||
End Target0_1.
|
||||
End Target0_2.
|
||||
End Target0_3.
|
||||
Done.
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target1 (1)
|
||||
Target2 (1,2)
|
||||
Target3 (1,2,3)
|
||||
Target4 (1,2,3,4)
|
||||
Target5 (1,2,3,4,5)
|
||||
Target6 (1,2,3,4,5,6)
|
||||
Target7 (1,2,3,4,5,6,7)
|
||||
Target8 (1,2,3,4,5,6,7,8)
|
||||
Target9 (1,2,3,4,5,6,7,8,9)
|
||||
Target10(1,2,3,4,5,6,7,8,9,10)
|
||||
Target11(1,2,3,4,5,6,7,8,9,10,11)
|
||||
Target12(1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
TargetV (0)
|
||||
TargetV (0,1)
|
||||
TargetV (0,1,2)
|
||||
TargetV (0,1,2,3)
|
||||
TargetV (0,1,2,3,4)
|
||||
TargetV (0,1,2,3,4,5)
|
||||
TargetV (0,1,2,3,4,5,6)
|
||||
TargetV (0,1,2,3,4,5,6,7)
|
||||
TargetV (0,1,2,3,4,5,6,7,8)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
|
||||
TargetV (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
|
||||
::: TargetR (0,1,2,3,1)
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TargetR (0,1,2,3,4,5,6,7,8,9,10,1)
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
Target0 ()
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dtarge.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "dtarge.h"
|
||||
|
||||
DWORD_PTR WINAPI Target0()
|
||||
{
|
||||
printf(" Target0 ()\n");
|
||||
return 1000;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target1(DWORD_PTR v1)
|
||||
{
|
||||
printf(" Target1 (%ld)\n",
|
||||
(DWORD)v1);
|
||||
return 1001;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target2(DWORD_PTR v1, DWORD_PTR v2)
|
||||
{
|
||||
printf(" Target2 (%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2);
|
||||
return 1002;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target3(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3)
|
||||
{
|
||||
printf(" Target3 (%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3);
|
||||
return 1003;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target4(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4)
|
||||
{
|
||||
printf(" Target4 (%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4);
|
||||
return 1004;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target5(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5)
|
||||
{
|
||||
printf(" Target5 (%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5);
|
||||
return 1005;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target6(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6)
|
||||
{
|
||||
printf(" Target6 (%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6);
|
||||
return 1006;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target7(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7)
|
||||
{
|
||||
printf(" Target7 (%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7);
|
||||
return 1007;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target8(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8)
|
||||
{
|
||||
printf(" Target8 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8);
|
||||
return 1008;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target9(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9)
|
||||
{
|
||||
printf(" Target9 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9);
|
||||
return 1009;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target10(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10)
|
||||
{
|
||||
printf(" Target10(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10);
|
||||
return 1010;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target11(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11)
|
||||
{
|
||||
printf(" Target11(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11);
|
||||
return 1011;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target12(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12)
|
||||
{
|
||||
printf(" Target12(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12);
|
||||
return 1012;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target13(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13)
|
||||
{
|
||||
printf(" Target13(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13);
|
||||
return 1013;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target14(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14)
|
||||
{
|
||||
printf(" Target14(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13, (DWORD)v14);
|
||||
return 1014;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target15(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15)
|
||||
{
|
||||
printf(" Target15(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13, (DWORD)v14, (DWORD)v15);
|
||||
return 1015;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI Target16(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16)
|
||||
{
|
||||
printf(" Target16(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13, (DWORD)v14, (DWORD)v15, (DWORD)v16);
|
||||
return 1016;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI TargetV(DWORD_PTR v1, ...)
|
||||
{
|
||||
DWORD_PTR args[32];
|
||||
|
||||
va_list va;
|
||||
va_start(va, v1);
|
||||
|
||||
int argc = 0;
|
||||
for (args[argc++] = v1; args[argc-1] != 0;) {
|
||||
args[argc++] = va_arg(va, DWORD_PTR);
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
printf(" TargetV (");
|
||||
int i = argc - 1;
|
||||
for (; i > 0; i--) {
|
||||
printf("%ld,", (DWORD)args[i]);
|
||||
}
|
||||
printf("%ld)\n", (DWORD)args[0]);
|
||||
|
||||
return 1000 + argc;
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI TargetR(DWORD_PTR v1, ...)
|
||||
{
|
||||
DWORD_PTR args[32];
|
||||
|
||||
va_list va;
|
||||
va_start(va, v1);
|
||||
|
||||
int argc = 0;
|
||||
for (args[argc++] = v1; args[argc-1] != 0;) {
|
||||
args[argc++] = va_arg(va, DWORD_PTR);
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
if (v1 > 1) {
|
||||
printf(":");
|
||||
switch (argc) {
|
||||
default:
|
||||
return TargetR(0) + 1;
|
||||
case 1:
|
||||
return TargetR(args[0] - 1) + 1;
|
||||
case 2:
|
||||
return TargetR(args[0] - 1, args[1]) + 1;
|
||||
case 3:
|
||||
return TargetR(args[0] - 1, args[1], args[2]) + 1;
|
||||
case 4:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3]) + 1;
|
||||
case 5:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4]) + 1;
|
||||
case 6:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5]) + 1;
|
||||
case 7:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6]) + 1;
|
||||
case 8:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7]) + 1;
|
||||
case 9:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8]) + 1;
|
||||
case 10:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9]) + 1;
|
||||
case 11:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10]) + 1;
|
||||
case 12:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11]) + 1;
|
||||
case 13:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12]) + 1;
|
||||
case 14:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13]) + 1;
|
||||
case 15:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14]) + 1;
|
||||
case 16:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14], args[15]) + 1;
|
||||
case 17:
|
||||
return TargetR(args[0] - 1, args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14], args[15],
|
||||
args[16]) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf(" TargetR (");
|
||||
int i = argc - 1;
|
||||
for (; i > 0; i--) {
|
||||
printf("%ld,", (DWORD)args[i]);
|
||||
}
|
||||
printf("%ld)\n", (DWORD)args[0]);
|
||||
|
||||
return 2000 + argc;
|
||||
}
|
||||
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
(void)hinst;
|
||||
(void)dwReason;
|
||||
(void)reserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dtarge.h of dtarge.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#if (_MSC_VER < 1299)
|
||||
typedef DWORD DWORD_PTR;
|
||||
#endif
|
||||
|
||||
DWORD_PTR WINAPI Target0();
|
||||
DWORD_PTR WINAPI Target1(DWORD_PTR v1);
|
||||
DWORD_PTR WINAPI Target2(DWORD_PTR v1, DWORD_PTR v2);
|
||||
DWORD_PTR WINAPI Target3(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3);
|
||||
DWORD_PTR WINAPI Target4(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4);
|
||||
DWORD_PTR WINAPI Target5(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5);
|
||||
DWORD_PTR WINAPI Target6(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6);
|
||||
DWORD_PTR WINAPI Target7(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7);
|
||||
DWORD_PTR WINAPI Target8(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8);
|
||||
DWORD_PTR WINAPI Target9(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9);
|
||||
DWORD_PTR WINAPI Target10(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10);
|
||||
DWORD_PTR WINAPI Target11(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11);
|
||||
DWORD_PTR WINAPI Target12(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12);
|
||||
DWORD_PTR WINAPI Target13(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13);
|
||||
DWORD_PTR WINAPI Target14(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14);
|
||||
DWORD_PTR WINAPI Target15(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15);
|
||||
DWORD_PTR WINAPI Target16(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16);
|
||||
DWORD_PTR WINAPI TargetV(DWORD_PTR v1, ...);
|
||||
DWORD_PTR WINAPI TargetR(DWORD_PTR v1, ...);
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for dtarge.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "dtarge" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "dtarge" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,658 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dtest.cpp of dtest.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <windows.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
#include <detours.h>
|
||||
#include "dtarge.h"
|
||||
|
||||
DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1);
|
||||
|
||||
////////////////////////////////////////////////////// Multi-Argument Detours.
|
||||
//
|
||||
DWORD_PTR (WINAPI * Trampoline_LocalTarget1)(DWORD_PTR v1) = LocalTarget1;
|
||||
|
||||
DWORD_PTR (WINAPI * Trampoline_Target0)() = Target0;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target1)(DWORD_PTR v1) = Target1;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target2)(DWORD_PTR v1, DWORD_PTR v2) = Target2;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target3)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3) = Target3;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target4)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4) = Target4;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target5)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5) = Target5;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target6)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6) = Target6;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target7)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7) = Target7;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target8)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8) = Target8;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target9)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9) = Target9;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target10)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10) = Target10;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target11)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11) = Target11;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target12)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12) = Target12;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target13)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13) = Target13;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target14)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14) = Target14;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target15)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15) = Target15;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target16)
|
||||
(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16) = Target16;
|
||||
DWORD_PTR (WINAPI * Trampoline_TargetV)(DWORD_PTR v1, ...) = TargetV;
|
||||
DWORD_PTR (WINAPI * Trampoline_TargetR)(DWORD_PTR v1, ...) = TargetR;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
VOID dprintf(const char * fmt, ...)
|
||||
{
|
||||
CHAR szBuf[1024];
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
StringCchPrintfA(szBuf, sizeof(szBuf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
OutputDebugStringA(szBuf);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
DWORD_PTR WINAPI LocalTarget1(DWORD_PTR v1)
|
||||
{
|
||||
printf(" LocalTarget1 (%ld)\n", (DWORD)v1);
|
||||
// dprintf("LocalTarget1\n");
|
||||
// __debugbreak();
|
||||
return 9000;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
DWORD_PTR WINAPI MyLocalTarget1(DWORD_PTR v1)
|
||||
{
|
||||
printf(" MyLocalTarget1 (%ld)\n",
|
||||
(DWORD)v1);
|
||||
// dprintf("LocalTarget1, Trampoline_LocalTarget1=%p\n", Trampoline_LocalTarget1);
|
||||
return Trampoline_LocalTarget1(v1);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget0()
|
||||
{
|
||||
printf(" MyTarget0 ()\n");
|
||||
return Trampoline_Target0();
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget1(DWORD_PTR v1)
|
||||
{
|
||||
printf(" MyTarget1 (%ld)\n",
|
||||
(DWORD)v1);
|
||||
return Trampoline_Target1(v1);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget2(DWORD_PTR v1, DWORD_PTR v2)
|
||||
{
|
||||
printf(" MyTarget2 (%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2);
|
||||
return Trampoline_Target2(v1,v2);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget3(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3)
|
||||
{
|
||||
printf(" MyTarget3 (%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3);
|
||||
return Trampoline_Target3(v1,v2,v3);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget4(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4)
|
||||
{
|
||||
printf(" MyTarget4 (%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4);
|
||||
return Trampoline_Target4(v1,v2,v3,v4);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget5(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5)
|
||||
{
|
||||
printf(" MyTarget5 (%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5);
|
||||
return Trampoline_Target5(v1,v2,v3,v4,v5);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget6(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6)
|
||||
{
|
||||
printf(" MyTarget6 (%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6);
|
||||
return Trampoline_Target6(v1,v2,v3,v4,v5,v6);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget7(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7)
|
||||
{
|
||||
printf(" MyTarget7 (%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7);
|
||||
return Trampoline_Target7(v1,v2,v3,v4,v5,v6,v7);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget8(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8)
|
||||
{
|
||||
printf(" MyTarget8 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8);
|
||||
return Trampoline_Target8(v1,v2,v3,v4,v5,v6,v7,v8);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget9(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9)
|
||||
{
|
||||
printf(" MyTarget9 (%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9);
|
||||
return Trampoline_Target9(v1,v2,v3,v4,v5,v6,v7,v8,v9);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget10(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10)
|
||||
{
|
||||
printf(" MyTarget10(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10);
|
||||
return Trampoline_Target10(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget11(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11)
|
||||
{
|
||||
printf(" MyTarget11(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11);
|
||||
return Trampoline_Target11(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget12(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12)
|
||||
{
|
||||
printf(" MyTarget12(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12);
|
||||
return Trampoline_Target12(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget13(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13)
|
||||
{
|
||||
printf(" MyTarget13(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13);
|
||||
return Trampoline_Target13(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget14(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14)
|
||||
{
|
||||
printf(" MyTarget14(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13, (DWORD)v14);
|
||||
return Trampoline_Target14(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget15(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15)
|
||||
{
|
||||
printf(" MyTarget15(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13, (DWORD)v14, (DWORD)v15);
|
||||
return Trampoline_Target15(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTarget16(DWORD_PTR v1, DWORD_PTR v2, DWORD_PTR v3, DWORD_PTR v4,
|
||||
DWORD_PTR v5, DWORD_PTR v6, DWORD_PTR v7, DWORD_PTR v8,
|
||||
DWORD_PTR v9, DWORD_PTR v10, DWORD_PTR v11, DWORD_PTR v12,
|
||||
DWORD_PTR v13, DWORD_PTR v14, DWORD_PTR v15, DWORD_PTR v16)
|
||||
{
|
||||
printf(" MyTarget16(%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld)\n",
|
||||
(DWORD)v1, (DWORD)v2, (DWORD)v3, (DWORD)v4,
|
||||
(DWORD)v5, (DWORD)v6, (DWORD)v7, (DWORD)v8,
|
||||
(DWORD)v9, (DWORD)v10, (DWORD)v11, (DWORD)v12,
|
||||
(DWORD)v13, (DWORD)v14, (DWORD)v15, (DWORD)v16);
|
||||
return Trampoline_Target16(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16);
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTargetV(DWORD_PTR v1, ...)
|
||||
{
|
||||
DWORD_PTR args[32];
|
||||
|
||||
va_list va;
|
||||
va_start(va, v1);
|
||||
|
||||
int argc = 0;
|
||||
for (args[argc++] = v1; args[argc-1] != 0;) {
|
||||
args[argc++] = va_arg(va, DWORD_PTR);
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
printf(" MyTargetV (");
|
||||
int i = argc - 1;
|
||||
for (; i > 0; i--) {
|
||||
printf("%ld,", (DWORD)args[i]);
|
||||
}
|
||||
printf("%ld)\n", (DWORD)args[0]);
|
||||
|
||||
switch (argc) {
|
||||
default:
|
||||
return Trampoline_TargetV(0);
|
||||
case 1:
|
||||
return Trampoline_TargetV(args[0]);
|
||||
case 2:
|
||||
return Trampoline_TargetV(args[0], args[1]);
|
||||
case 3:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2]);
|
||||
case 4:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3]);
|
||||
case 5:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4]);
|
||||
case 6:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5]);
|
||||
case 7:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6]);
|
||||
case 8:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7]);
|
||||
case 9:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8]);
|
||||
case 10:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9]);
|
||||
case 11:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10]);
|
||||
case 12:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11]);
|
||||
case 13:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12]);
|
||||
case 14:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13]);
|
||||
case 15:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14]);
|
||||
case 16:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14], args[15]);
|
||||
case 17:
|
||||
return Trampoline_TargetV(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14], args[15],
|
||||
args[16]);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD_PTR WINAPI MyTargetR(DWORD_PTR v1, ...)
|
||||
{
|
||||
DWORD_PTR args[32];
|
||||
|
||||
va_list va;
|
||||
va_start(va, v1);
|
||||
|
||||
int argc = 0;
|
||||
for (args[argc++] = v1; args[argc-1] != 0;) {
|
||||
args[argc++] = va_arg(va, DWORD_PTR);
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
if (v1 < 5) {
|
||||
printf(" MyTargetR (");
|
||||
int i = argc - 1;
|
||||
for (; i > 0; i--) {
|
||||
printf("%ld,", (DWORD)args[i]);
|
||||
}
|
||||
printf("%ld)\n", (DWORD)args[0]);
|
||||
}
|
||||
else {
|
||||
printf(".");
|
||||
}
|
||||
|
||||
switch (argc) {
|
||||
default:
|
||||
return Trampoline_TargetR(0);
|
||||
case 1:
|
||||
return Trampoline_TargetR(args[0]);
|
||||
case 2:
|
||||
return Trampoline_TargetR(args[0], args[1]);
|
||||
case 3:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2]);
|
||||
case 4:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3]);
|
||||
case 5:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4]);
|
||||
case 6:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5]);
|
||||
case 7:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6]);
|
||||
case 8:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7]);
|
||||
case 9:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8]);
|
||||
case 10:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9]);
|
||||
case 11:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10]);
|
||||
case 12:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11]);
|
||||
case 13:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12]);
|
||||
case 14:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13]);
|
||||
case 15:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14]);
|
||||
case 16:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14], args[15]);
|
||||
case 17:
|
||||
return Trampoline_TargetR(args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7],
|
||||
args[8], args[9], args[10], args[11],
|
||||
args[12], args[13], args[14], args[15],
|
||||
args[16]);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////// Recursive Detours.
|
||||
//
|
||||
DWORD_PTR (WINAPI * Trampoline_Target0_1)() = NULL;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target0_2)() = NULL;
|
||||
DWORD_PTR (WINAPI * Trampoline_Target0_3)() = NULL;
|
||||
|
||||
static DWORD_PTR WINAPI MyTarget0_1()
|
||||
{
|
||||
printf(" Starting Target0_1.\n");
|
||||
DWORD_PTR rv = Trampoline_Target0_1();
|
||||
printf(" End Target0_1.\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
static DWORD_PTR WINAPI MyTarget0_2()
|
||||
{
|
||||
printf(" Starting Target0_2.\n");
|
||||
DWORD_PTR rv = Trampoline_Target0_2();
|
||||
printf(" End Target0_2.\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
static DWORD_PTR WINAPI MyTarget0_3()
|
||||
{
|
||||
printf(" Starting Target0_3.\n");
|
||||
DWORD_PTR rv = Trampoline_Target0_3();
|
||||
printf(" End Target0_3.\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
(void)hinst;
|
||||
(void)hprev;
|
||||
(void)lpszCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
printf("Calling LocalTarget1 w/o detour\n");
|
||||
LocalTarget1(1);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Trampoline_LocalTarget1, MyLocalTarget1);
|
||||
DetourTransactionCommit();
|
||||
|
||||
printf("Calling LocalTarget1 w/ detour\n");
|
||||
LocalTarget1(2);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Trampoline_Target0, MyTarget0);
|
||||
DetourTransactionCommit();
|
||||
|
||||
printf("Calling Target0 function.\n");
|
||||
//dprintf("- Trampoline_Target0:: %p\n", Trampoline_Target0);
|
||||
//dprintf("- Target0 :: %p\n", Target0);
|
||||
Target0();
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Trampoline_Target1, MyTarget1);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target2, MyTarget2);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target3, MyTarget3);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target4, MyTarget4);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target5, MyTarget5);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target6, MyTarget6);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target7, MyTarget7);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target8, MyTarget8);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target9, MyTarget9);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target10, MyTarget10);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target11, MyTarget11);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target12, MyTarget12);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target13, MyTarget13);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target14, MyTarget14);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target15, MyTarget15);
|
||||
DetourAttach(&(PVOID&)Trampoline_Target16, MyTarget16);
|
||||
DetourAttach(&(PVOID&)Trampoline_TargetV, MyTargetV);
|
||||
DetourAttach(&(PVOID&)Trampoline_TargetR, MyTargetR);
|
||||
DetourTransactionCommit();
|
||||
|
||||
printf("Calling TargetN functions.\n");
|
||||
LocalTarget1(1);
|
||||
Target0();
|
||||
Target1(1);
|
||||
Target2(1,2);
|
||||
Target3(1,2,3);
|
||||
Target4(1,2,3,4);
|
||||
Target5(1,2,3,4,5);
|
||||
Target6(1,2,3,4,5,6);
|
||||
Target7(1,2,3,4,5,6,7);
|
||||
Target8(1,2,3,4,5,6,7,8);
|
||||
Target9(1,2,3,4,5,6,7,8,9);
|
||||
Target10(1,2,3,4,5,6,7,8,9,10);
|
||||
Target11(1,2,3,4,5,6,7,8,9,10,11);
|
||||
Target12(1,2,3,4,5,6,7,8,9,10,11,12);
|
||||
Target13(1,2,3,4,5,6,7,8,9,10,11,12,13);
|
||||
Target14(1,2,3,4,5,6,7,8,9,10,11,12,13,14);
|
||||
Target15(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
|
||||
Target16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
|
||||
TargetV(0);
|
||||
TargetV(1,0);
|
||||
TargetV(2,1,0);
|
||||
TargetV(3,2,1,0);
|
||||
TargetV(4,3,2,1,0);
|
||||
TargetV(5,4,3,2,1,0);
|
||||
TargetV(6,5,4,3,2,1,0);
|
||||
TargetV(7,6,5,4,3,2,1,0);
|
||||
TargetV(8,7,6,5,4,3,2,1,0);
|
||||
TargetV(9,8,7,6,5,4,3,2,1,0);
|
||||
TargetV(10,9,8,7,6,5,4,3,2,1,0);
|
||||
TargetV(11,10,9,8,7,6,5,4,3,2,1,0);
|
||||
TargetV(12,11,10,9,8,7,6,5,4,3,2,1,0);
|
||||
TargetV(13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
||||
TargetV(14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
||||
TargetV(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
||||
TargetV(16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
|
||||
TargetR(4,3,2,1,0);
|
||||
DWORD_PTR rv = TargetR(100,10,9,8,7,6,5,4,3,2,1,0);
|
||||
printf(" => %ld\n", (DWORD)rv);
|
||||
|
||||
Trampoline_Target0_1 = Target0;
|
||||
Trampoline_Target0_2 = Target0;
|
||||
Trampoline_Target0_3 = Target0;
|
||||
|
||||
//dprintf("Trampoline_Target0_1 = %p\n", DetourCodeFromPointer(Trampoline_Target0_1, NULL));
|
||||
//__debugbreak();
|
||||
|
||||
printf("Calling Target0 again with 1 detour.\n");
|
||||
Target0();
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Trampoline_Target0_1, MyTarget0_1);
|
||||
DetourTransactionCommit();
|
||||
|
||||
//dprintf("Trampoline_Target0_2 = %p\n", DetourCodeFromPointer(Trampoline_Target0_2, NULL));
|
||||
//__debugbreak();
|
||||
printf("Calling Target0 again with 2 detours.\n");
|
||||
Target0();
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Trampoline_Target0_2, MyTarget0_2);
|
||||
DetourTransactionCommit();
|
||||
|
||||
//dprintf("Trampoline_Target0_3 = %p\n", DetourCodeFromPointer(Trampoline_Target0_3, NULL));
|
||||
//__debugbreak();
|
||||
printf("Calling Target0 again with 3 detours.\n");
|
||||
Target0();
|
||||
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Trampoline_Target0_3, MyTarget0_3);
|
||||
DetourTransactionCommit();
|
||||
|
||||
//dprintf("Trampoline_Target0_3 = %p\n", DetourCodeFromPointer(Trampoline_Target0_3, NULL));
|
||||
//__debugbreak();
|
||||
printf("Calling Target0 again with 4 detours.\n");
|
||||
Target0();
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)Trampoline_Target0, MyTarget0);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target1, MyTarget1);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target2, MyTarget2);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target3, MyTarget3);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target4, MyTarget4);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target5, MyTarget5);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target6, MyTarget6);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target7, MyTarget7);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target8, MyTarget8);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target9, MyTarget9);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target10, MyTarget10);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target11, MyTarget11);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target12, MyTarget12);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target13, MyTarget13);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target14, MyTarget14);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target15, MyTarget15);
|
||||
DetourDetach(&(PVOID&)Trampoline_Target16, MyTarget16);
|
||||
DetourDetach(&(PVOID&)Trampoline_TargetV, MyTargetV);
|
||||
DetourDetach(&(PVOID&)Trampoline_TargetR, MyTargetR);
|
||||
DetourTransactionCommit();
|
||||
|
||||
printf("Done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\dumpe.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\dumpe.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\dumpe.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\dumpe.obj : dumpe.cpp
|
||||
|
||||
$(BIND)\dumpe.exe : $(OBJD)\dumpe.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dumpe.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\dumpe.bsc : $(OBJD)\dumpe.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dumpe.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\dumpe.exe
|
||||
$(BIND)\dumpe.exe $(BIND)\slept.dll
|
||||
|
||||
testx: $(BIND)\dumpe.exe
|
||||
cd $(MAKEDIR)\..\..\src
|
||||
nmake
|
||||
cd $(MAKEDIR)
|
||||
if exist $(SYSTEMROOT)\system32\browseui.dll $(BIND)\dumpe.exe browseui.dll
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dumpe.cpp of dumpe.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <shellapi.h>
|
||||
#include "detours.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#ifndef NODEBUG
|
||||
#undef ASSERT
|
||||
VOID DetourAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, DWORD nLine);
|
||||
|
||||
#define ASSERT(x) \
|
||||
do { if (!(x)) { DetourAssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
|
||||
;
|
||||
#undef ASSERTX
|
||||
#define ASSERTX(x) \
|
||||
do { if (!(x)) { DetourAssertMessage(#x, __FILE__, __LINE__); PCHAR p=(PCHAR)(x); *p = 1; }} while (0)
|
||||
;
|
||||
#else // NODEBUG
|
||||
#undef ASSERT
|
||||
#define ASSERT(x)
|
||||
#undef ASSERTX
|
||||
#define ASSERTX(x)
|
||||
#endif // NODEBUG
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////// Error Messages.
|
||||
//
|
||||
VOID DetourAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, DWORD nLine)
|
||||
{
|
||||
printf("ASSERT(%s) failed in %s, line %ld.", szMsg, szFile, nLine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static BOOL CALLBACK ExportCallback(PVOID pContext,
|
||||
ULONG nOrdinal,
|
||||
LPCSTR pszSymbol,
|
||||
PVOID pbTarget)
|
||||
{
|
||||
(void)pContext;
|
||||
|
||||
printf(" %7ld %p %-30s\n",
|
||||
(ULONG)nOrdinal,
|
||||
pbTarget,
|
||||
pszSymbol ? pszSymbol : "[NONAME]");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DumpFile(PCHAR pszPath)
|
||||
{
|
||||
HINSTANCE hInst = LoadLibraryA(pszPath);
|
||||
if (hInst == NULL) {
|
||||
printf("Unable to load %s: Error %ld\n", pszPath, GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("%s @ %p\n", pszPath, hInst);
|
||||
|
||||
PVOID pbEntry = DetourGetEntryPoint(hInst);
|
||||
printf(" EntryPoint: %p\n", pbEntry);
|
||||
|
||||
printf(" Ordinal RVA Name\n");
|
||||
DetourEnumerateExports(hInst, NULL, ExportCallback);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void PrintUsage(void)
|
||||
{
|
||||
printf("Usage:\n"
|
||||
" dumpe [.dll files]\n"
|
||||
"Misc. Options:\n"
|
||||
" /? : Help screen.\n");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////// main.
|
||||
//
|
||||
int CDECL main(int argc, char **argv)
|
||||
{
|
||||
BOOL fNeedHelp = FALSE;
|
||||
|
||||
int arg = 1;
|
||||
for (; arg < argc; arg++) {
|
||||
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
|
||||
CHAR *argn = argv[arg] + 1;
|
||||
CHAR *argp = argn;
|
||||
while (*argp && *argp != ':')
|
||||
argp++;
|
||||
if (*argp == ':')
|
||||
*argp++ = '\0';
|
||||
|
||||
switch (argn[0]) {
|
||||
|
||||
case '?': // Help.
|
||||
fNeedHelp = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
fNeedHelp = TRUE;
|
||||
printf("Bad argument: %s:%s\n", argn, argp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DumpFile(argv[arg]);
|
||||
}
|
||||
}
|
||||
if (fNeedHelp || argc == 1) {
|
||||
PrintUsage();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// End of File
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs - Dump Imports
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\dumpi.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\dumpi.bsc \
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\dumpi.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\dumpi.obj : dumpi.cpp
|
||||
|
||||
$(BIND)\dumpi.exe : $(OBJD)\dumpi.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\dumpi.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\dumpi.bsc : $(OBJD)\dumpi.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dumpi.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\dumpi.exe
|
||||
$(BIND)\dumpi.exe $(BIND)\slept.dll $(BIND)\sleepold.exe
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (dumpi.cpp of dumpi.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
#include <detours.h>
|
||||
|
||||
////////////////////////////////////////////////////////////// Error Messages.
|
||||
//
|
||||
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
|
||||
{
|
||||
printf("ASSERT(%s) failed in %s, line %ld.", szMsg, szFile, nLine);
|
||||
}
|
||||
|
||||
#define ASSERT(x) \
|
||||
do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
|
||||
;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static CHAR s_szFile[MAX_PATH] = "\0";
|
||||
|
||||
static BOOL CALLBACK ListFileCallback(_In_opt_ PVOID pContext,
|
||||
_In_z_ LPCSTR pszOrigFile,
|
||||
_In_z_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)pszFile;
|
||||
|
||||
*ppszOutFile = NULL;
|
||||
|
||||
StringCchCopyA(s_szFile, sizeof(s_szFile), pszOrigFile);
|
||||
|
||||
PCHAR psz;
|
||||
if ((psz = strchr(s_szFile, '.')) != NULL) {
|
||||
*psz = '\0';
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK ListSymbolCallback(_In_opt_ PVOID pContext,
|
||||
_In_ ULONG nOrigOrdinal,
|
||||
_In_ ULONG nOrdinal,
|
||||
_Out_ ULONG *pnOutOrdinal,
|
||||
_In_opt_z_ LPCSTR pszOrigSymbol,
|
||||
_In_opt_z_ LPCSTR pszSymbol,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)nOrdinal;
|
||||
(void)pszSymbol;
|
||||
|
||||
*ppszOutSymbol = NULL;
|
||||
*pnOutOrdinal = 0;
|
||||
|
||||
if (nOrigOrdinal != 0) {
|
||||
printf(" %s::#%ld\n",
|
||||
s_szFile, nOrigOrdinal);
|
||||
}
|
||||
else {
|
||||
printf(" %s::%s\n",
|
||||
s_szFile, pszOrigSymbol);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DimpFile(PCHAR pszPath)
|
||||
{
|
||||
BOOL bGood = TRUE;
|
||||
HANDLE hOld = INVALID_HANDLE_VALUE;
|
||||
PDETOUR_BINARY pBinary = NULL;
|
||||
|
||||
|
||||
hOld = CreateFileA(pszPath,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (hOld == INVALID_HANDLE_VALUE) {
|
||||
printf("%s: Failed to open input file with error: %ld\n",
|
||||
pszPath, GetLastError());
|
||||
bGood = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
|
||||
printf("%s: DetourBinaryOpen failed: %ld\n", pszPath, GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (hOld != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hOld);
|
||||
hOld = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
printf("%s:\n", pszPath);
|
||||
if (!DetourBinaryEditImports(pBinary,
|
||||
NULL,
|
||||
NULL,
|
||||
ListFileCallback,
|
||||
ListSymbolCallback,
|
||||
NULL)) {
|
||||
|
||||
printf("%s: DetourBinaryEditImports failed: %ld\n", pszPath, GetLastError());
|
||||
}
|
||||
|
||||
DetourBinaryClose(pBinary);
|
||||
pBinary = NULL;
|
||||
|
||||
end:
|
||||
if (pBinary) {
|
||||
DetourBinaryClose(pBinary);
|
||||
pBinary = NULL;
|
||||
}
|
||||
if (hOld != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hOld);
|
||||
hOld = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return bGood;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
int DimpArgument(char *dir, char *argp, int fDoSubs)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
WIN32_FIND_DATAA wfd;
|
||||
HANDLE hFind = NULL;
|
||||
char name[1024];
|
||||
int nFound = 0;
|
||||
|
||||
StringCchCopyA(name, sizeof(name), dir ? dir : "");
|
||||
StringCchCatA(name, sizeof(name), argp);
|
||||
|
||||
hFind = FindFirstFileA(name, &wfd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
StringCchCopyA(name, sizeof(name), dir ? dir : "");
|
||||
StringCchCatA(name, sizeof(name), wfd.cFileName);
|
||||
|
||||
nFound += DimpFile(name);
|
||||
}
|
||||
} while (FindNextFileA(hFind, &wfd));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
if (fDoSubs) {
|
||||
StringCchCopyA(name, sizeof(name), dir ? dir : "");
|
||||
StringCchCatA(name, sizeof(name), "*");
|
||||
|
||||
hFind = FindFirstFileA(name, &wfd);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return nFound;
|
||||
|
||||
do {
|
||||
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
wfd.cFileName[0] != '.') {
|
||||
|
||||
StringCchCopyA(name, sizeof(name), dir ? dir : "");
|
||||
StringCchCatA(name, sizeof(name), wfd.cFileName);
|
||||
StringCchCatA(name, sizeof(name), "\\");
|
||||
|
||||
nFound += DimpArgument(name, argp, fDoSubs);
|
||||
}
|
||||
} while (FindNextFileA(hFind, &wfd));
|
||||
FindClose(hFind);
|
||||
}
|
||||
return nFound;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void PrintUsage(void)
|
||||
{
|
||||
printf("Usage:\n"
|
||||
" dimp [options] binary_files\n"
|
||||
"Options:\n"
|
||||
" /s : Recurse through subdirectories.\n"
|
||||
" /? : This help screen.\n"
|
||||
"Examples:\n"
|
||||
" dimp /s *.exe\n"
|
||||
"");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////// main.
|
||||
//
|
||||
int CDECL main(int argc, char **argv)
|
||||
{
|
||||
BOOL fNeedHelp = FALSE;
|
||||
BOOL fSubdirs = FALSE;
|
||||
|
||||
int arg = 1;
|
||||
for (; arg < argc; arg++) {
|
||||
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
|
||||
CHAR *argn = argv[arg] + 1;
|
||||
CHAR *argp = argn;
|
||||
while (*argp && *argp != ':')
|
||||
argp++;
|
||||
if (*argp == ':')
|
||||
*argp++ = '\0';
|
||||
|
||||
switch (argn[0]) {
|
||||
|
||||
case 's': // Do Subdirectories.
|
||||
case 'S':
|
||||
fSubdirs = TRUE;
|
||||
break;
|
||||
|
||||
case '?': // Help.
|
||||
fNeedHelp = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
fNeedHelp = TRUE;
|
||||
printf("Bad argument: %s:%s\n", argn, argp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CHAR szDir[MAX_PATH] = "";
|
||||
CHAR szArg[MAX_PATH] = "";
|
||||
PCHAR pszDir;
|
||||
|
||||
if ((pszDir = strrchr(argv[arg], '\\')) != NULL) {
|
||||
*pszDir++ = '\0';
|
||||
StringCchCopyA(szArg, sizeof(szArg), pszDir);
|
||||
StringCchCopyA(szDir, sizeof(szDir), argv[arg]);
|
||||
StringCchCatA(szDir, sizeof(szDir), "\\");
|
||||
}
|
||||
else {
|
||||
if (GetCurrentDirectoryA(sizeof(szDir), szDir) > 3) {
|
||||
StringCchCatA(szDir, sizeof(szDir), "\\");
|
||||
}
|
||||
StringCchCopyA(szArg, sizeof(szArg), argv[arg]);
|
||||
}
|
||||
|
||||
DimpArgument(szDir, szArg, fSubdirs);
|
||||
}
|
||||
}
|
||||
if (argc == 1) {
|
||||
fNeedHelp = TRUE;
|
||||
}
|
||||
if (fNeedHelp) {
|
||||
PrintUsage();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// End of File
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
# This test is x86 only
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X86" || "$(DETOURS_TARGET_PROCESSOR)" == "X64"
|
||||
|
||||
TARGET_NAME=dalloc
|
||||
CFLAGS=\
|
||||
$(CFLAGS)\
|
||||
/EHsc\
|
||||
|
||||
LIBS=$(LIBS)\
|
||||
user32.lib\
|
||||
|
||||
all: dirs $(BIND)\$(TARGET_NAME).exe
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del $(BIND)\$(TARGET_NAME).* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
!IF "$(DETOURS_TARGET_PROCESSOR)" == "X64"
|
||||
$(OBJD)\asm.obj : x64.asm
|
||||
$(ASM) $(AFLAGS) /Fl$(OBJD)\x64.lst /Fo$(OBJD)\asm.obj x64.asm
|
||||
!ELSE
|
||||
$(OBJD)\asm.obj : x86.asm
|
||||
$(ASM) $(AFLAGS) /Fl$(OBJD)\x86.lst /Fo$(OBJD)\asm.obj x86.asm
|
||||
!ENDIF
|
||||
|
||||
$(OBJD)\main.obj : main.cpp
|
||||
|
||||
$(BIND)\$(TARGET_NAME).exe : $(OBJD)\main.obj $(OBJD)\asm.obj $(DEPS)
|
||||
link\
|
||||
/SUBSYSTEM:CONSOLE\
|
||||
$(LINKFLAGS)\
|
||||
$(LIBS)\
|
||||
/PDB:"$(@R).pdb"\
|
||||
/OUT:"$@"\
|
||||
$**\
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
$(BIND)\$(TARGET_NAME).exe
|
||||
|
||||
##############################################################################
|
||||
|
||||
!ELSE
|
||||
|
||||
all:
|
||||
@echo The platform `$(DETOURS_TARGET_PROCESSOR)` is not supported. Skipping.
|
||||
test:
|
||||
@echo The platform `$(DETOURS_TARGET_PROCESSOR)` is not supported. Skipping.
|
||||
clean:
|
||||
realclean:
|
||||
|
||||
!ENDIF
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This is a test program to test the DetourAllocateRegionWithinJumpBounds
|
||||
// API, that dynamically allocates an executable region adjacent to a given
|
||||
// address so that we can use the region as a detour function.
|
||||
//
|
||||
// This test program detours the function `target_function`. Instead of
|
||||
// simply specifying a code segment as a detour function, we specify a
|
||||
// dynamically-allocated region into which we copy the code, altering the
|
||||
// return value, from the assembly function `CodeTemplate` as a template.
|
||||
//
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
extern "C" {
|
||||
void *CodeTemplate();
|
||||
void *CodeTemplate_End();
|
||||
}
|
||||
|
||||
void Log(PCSTR format, ...) {
|
||||
char linebuf[1024];
|
||||
va_list v;
|
||||
va_start(v, format);
|
||||
wvsprintfA(linebuf, format, v);
|
||||
va_end(v);
|
||||
OutputDebugStringA(linebuf);
|
||||
}
|
||||
|
||||
// This is a target function to be detoured. When detoured, it's expected to
|
||||
// return a non-nullptr value.
|
||||
void *target_function() {
|
||||
std::cout << '+' << __FUNCTION__ << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Helper function to sandwich a given function between `DetourTransactionBegin`
|
||||
// and `DetourTransactionCommit`/`DetourTransactionAbort`.
|
||||
bool DetourTransaction(std::function<bool()> callback) {
|
||||
LONG status = DetourTransactionBegin();
|
||||
if (status != NO_ERROR) {
|
||||
Log("DetourTransactionBegin failed with %08x\n", status);
|
||||
return status == NO_ERROR;
|
||||
}
|
||||
|
||||
if (callback()) {
|
||||
status = DetourTransactionCommit();
|
||||
if (status != NO_ERROR) {
|
||||
Log("DetourTransactionCommit failed with %08x\n", status);
|
||||
}
|
||||
}
|
||||
else {
|
||||
status = DetourTransactionAbort();
|
||||
if (status == NO_ERROR) {
|
||||
Log("Aborted transaction.\n");
|
||||
}
|
||||
else {
|
||||
Log("DetourTransactionAbort failed with %08x\n", status);
|
||||
}
|
||||
}
|
||||
return status == NO_ERROR;
|
||||
}
|
||||
|
||||
// This class manages one dynamically-allocated region that is allocated by
|
||||
// the Detours API `DetourAllocateRegionWithinJumpBounds`, to which we can
|
||||
// push binary data sequentially to use it as a detour function.
|
||||
class CodeRegionFactory final {
|
||||
template <typename T>
|
||||
static const T *at(const void *base, uint32_t offset) {
|
||||
return
|
||||
reinterpret_cast<const T*>(
|
||||
reinterpret_cast<const uint8_t*>(base) + offset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T *at(void *base, uint32_t offset) {
|
||||
return
|
||||
reinterpret_cast<T*>(
|
||||
reinterpret_cast<uint8_t*>(base) + offset);
|
||||
}
|
||||
|
||||
void *region_ = nullptr;
|
||||
uint8_t *current_ = nullptr,
|
||||
*current_end_ = nullptr;
|
||||
|
||||
public:
|
||||
CodeRegionFactory(const void *source) {
|
||||
DWORD new_region_size = 0;
|
||||
auto new_region_address =
|
||||
DetourAllocateRegionWithinJumpBounds(source, &new_region_size);
|
||||
if (new_region_address) {
|
||||
region_ = current_ = at<uint8_t>(new_region_address, 0);
|
||||
current_end_ = current_ + new_region_size;
|
||||
}
|
||||
else {
|
||||
Log("Cannot find a region near %p\n", source);
|
||||
}
|
||||
}
|
||||
|
||||
~CodeRegionFactory() {
|
||||
if (region_
|
||||
&& !VirtualFree(region_, 0, MEM_RELEASE)) {
|
||||
Log("VirtualFree failed - %08x\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
// Pushes binary data to the region if there is enough space, and returns
|
||||
// the start address of a copy in the region if succeeded.
|
||||
void *PushTemplate(const void *start,
|
||||
const void *end) {
|
||||
auto diff = at<uint8_t>(end, 0) - at<uint8_t>(start, 0);
|
||||
if (diff < 0 || current_ + diff > current_end_)
|
||||
return nullptr;
|
||||
auto start_pos = current_;
|
||||
memcpy(start_pos, start, diff);
|
||||
current_ += diff;
|
||||
return start_pos;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char**) {
|
||||
std::cout << "1. target_function() without Detour" << std::endl;
|
||||
auto ret = target_function();
|
||||
std::cout << ret << std::endl;
|
||||
assert(!ret);
|
||||
|
||||
CodeRegionFactory factory(target_function);
|
||||
|
||||
void *detour_destination,
|
||||
*detour_target = reinterpret_cast<void*>(target_function);
|
||||
|
||||
// Fill the allocated page with as many instances as possible of the code
|
||||
// template, and pick the last instance
|
||||
while (auto p = factory.PushTemplate(CodeTemplate,
|
||||
CodeTemplate_End)) {
|
||||
detour_destination = p;
|
||||
}
|
||||
|
||||
bool is_detoured = false;
|
||||
DetourTransaction([&]() {
|
||||
PDETOUR_TRAMPOLINE trampoline = nullptr;
|
||||
void *target = nullptr,
|
||||
*detour = nullptr;
|
||||
auto status = DetourAttachEx(&detour_target,
|
||||
detour_destination,
|
||||
&trampoline,
|
||||
&target,
|
||||
&detour);
|
||||
if (status != NO_ERROR) {
|
||||
Log("DetourAttachEx failed - %08x\n", status);
|
||||
return false;
|
||||
}
|
||||
is_detoured = true;
|
||||
std::cout
|
||||
<< "detour: " << target << " --> " << detour
|
||||
<< " (trampoline: " << trampoline << " )"
|
||||
<< std::endl;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Attach failed for some reason. Bail out.
|
||||
if (!is_detoured)
|
||||
return 1;
|
||||
|
||||
std::cout << "2. target_function() with Detour" << std::endl;
|
||||
ret = target_function();
|
||||
std::cout << ret << std::endl;
|
||||
assert(ret); // The return value is cracked by the detour function
|
||||
|
||||
DetourTransaction([&]() {
|
||||
auto status = DetourDetach(&detour_target, detour_destination);
|
||||
if (status != NO_ERROR) {
|
||||
Log("DetourDetach failed - %08x\n", status);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
std::cout << "3. target_function() without Detour" << std::endl;
|
||||
ret = target_function();
|
||||
std::cout << ret << std::endl;
|
||||
assert(!ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Detours Test Program
|
||||
;;
|
||||
;; Microsoft Research Detours Package
|
||||
;;
|
||||
;; Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
;;
|
||||
PUBLIC CodeTemplate
|
||||
PUBLIC CodeTemplate_End
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
CodeTemplate PROC
|
||||
nop
|
||||
nop
|
||||
mov rax, 0deadbeef00000000h
|
||||
nop
|
||||
ret
|
||||
CodeTemplate_End::
|
||||
CodeTemplate ENDP
|
||||
|
||||
_TEXT ENDS
|
||||
|
||||
END
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Detours Test Program
|
||||
;;
|
||||
;; Microsoft Research Detours Package
|
||||
;;
|
||||
;; Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
;;
|
||||
.386
|
||||
.model flat,C
|
||||
|
||||
PUBLIC CodeTemplate
|
||||
PUBLIC CodeTemplate_End
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
CodeTemplate PROC
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov eax, 0deadbeefh
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
ret
|
||||
CodeTemplate_End::
|
||||
CodeTemplate ENDP
|
||||
|
||||
_TEXT ENDS
|
||||
|
||||
END
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Detours Test Program
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\echofx$(DETOURS_BITS).dll \
|
||||
$(BIND)\echonul.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\echofx$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\echonul.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\echofx.obj : echofx.cpp
|
||||
|
||||
$(OBJD)\echofx.res : echofx.rc
|
||||
|
||||
$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echofx$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\echofx.obj $(OBJD)\echofx.res $(DEPS) $(BIND)\echonul.lib
|
||||
cl /LD $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
|
||||
$(OBJD)\echofx.obj $(OBJD)\echofx.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:Mine_Echo \
|
||||
$(LIBS) $(BIND)\echonul.lib
|
||||
|
||||
$(OBJD)\echofx$(DETOURS_BITS).bsc : $(OBJD)\echofx.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\echofx.sbr
|
||||
|
||||
$(OBJD)\echonul.obj : echonul.cpp
|
||||
$(OBJD)\main.obj : main.cpp
|
||||
|
||||
$(BIND)\echonul.exe $(BIND)\echonul.lib: $(OBJD)\main.obj $(OBJD)\echonul.obj
|
||||
cl $(CFLAGS) /Zl /Fe$(BIND)\echonul.exe /Fd$(@R).pdb \
|
||||
$(OBJD)\main.obj $(OBJD)\echonul.obj \
|
||||
/link $(LINKFLAGS) \
|
||||
/export:Echo \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\echonul.bsc : echonul.obj
|
||||
bscmake /v /n /o $@ echonul.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\echofx*.* 2>nul
|
||||
-del $(BIND)\echonul.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\echofx$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\echofx$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).dll : $(OPTD)\echofx$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).pdb : $(OPTD)\echofx$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\echofx$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Should echo nothing. --------------------------------------
|
||||
-$(BIND)\echonul.exe
|
||||
@echo -------- Should echo Hello World. ----------------------------------
|
||||
-$(BIND)\withdll.exe -d:$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echonul.exe
|
||||
@echo.
|
||||
|
||||
testd: all
|
||||
@echo.
|
||||
-windbg -o -g -G $(BIND)\withdll.exe -d:$(BIND)\echofx$(DETOURS_BITS).dll $(BIND)\echonul.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
//
|
||||
//
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int WINAPI Echo(PCSTR pszMsg);
|
||||
|
||||
static int (WINAPI * Real_Echo)(PCSTR pszMsg) = Echo;
|
||||
|
||||
int WINAPI Mine_Echo(PCSTR pszMsg)
|
||||
{
|
||||
printf("Echo(%s)\n", pszMsg);
|
||||
return Real_Echo(pszMsg);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Real_Echo, Mine_Echo);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured Echo().\n");
|
||||
}
|
||||
else {
|
||||
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring Echo(): %ld\n", error);
|
||||
}
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)Real_Echo, Mine_Echo);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Removed Echo() (result=%ld)\n", error);
|
||||
fflush(stdout);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for echofx.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "echofx" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "echofx" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Echo Interception Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
//
|
||||
//
|
||||
#include <windows.h>
|
||||
|
||||
int WINAPI Echo(PCSTR pszMsg)
|
||||
{
|
||||
int sum = 0;
|
||||
while (*pszMsg) {
|
||||
sum = sum + *pszMsg++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
//
|
||||
//
|
||||
#include <windows.h>
|
||||
|
||||
int WINAPI Echo(PCSTR pszMsg);
|
||||
|
||||
extern "C" int __stdcall mainCRTStartup(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)hPrevInstance;
|
||||
(void)lpCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
Echo("Hello World");
|
||||
Echo("Goodbye World");
|
||||
|
||||
return 0x99;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
# ARM64 does not like base addresses below 4GB.
|
||||
# Append two extra zeros for it.
|
||||
#
|
||||
!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
|
||||
EDLL1X_BASE=0x710000000
|
||||
EDLL2X_BASE=0x720000000
|
||||
EDLL3X_BASE=0x730000000
|
||||
!else
|
||||
EDLL1X_BASE=0x7100000
|
||||
EDLL2X_BASE=0x7200000
|
||||
EDLL3X_BASE=0x7300000
|
||||
!endif
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib user32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\edll1x$(DETOURS_BITS).dll \
|
||||
$(BIND)\edll2x$(DETOURS_BITS).dll \
|
||||
$(BIND)\edll3x$(DETOURS_BITS).dll \
|
||||
$(BIND)\einst.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\edll1x$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\edll2x$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\edll3x$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\einst.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\edll1x*.* 2>nul
|
||||
-del $(BIND)\edll2x*.* 2>nul
|
||||
-del $(BIND)\edll3x*.* 2>nul
|
||||
-del $(BIND)\einst.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
##############################################################################
|
||||
|
||||
$(OBJD)\einst.obj : einst.cpp
|
||||
|
||||
$(BIND)\einst.exe : $(OBJD)\einst.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\einst.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
$(BIND)\edll1x$(DETOURS_BITS).lib $(BIND)\edll2x$(DETOURS_BITS).lib $(BIND)\edll3x$(DETOURS_BITS).lib \
|
||||
/subsystem:console /entry:WinMainCRTStartup
|
||||
|
||||
$(OBJD)\einst.bsc : $(OBJD)\einst.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\einst.sbr
|
||||
|
||||
$(OBJD)\edll1x.obj : edll1x.cpp
|
||||
|
||||
$(BIND)\edll1x$(DETOURS_BITS).dll : $(OBJD)\edll1x.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
|
||||
$(OBJD)\edll1x.obj /LD \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:windows \
|
||||
/base:$(EDLL1X_BASE)
|
||||
|
||||
$(OBJD)\edll1x$(DETOURS_BITS).bsc : $(OBJD)\edll1x.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\edll1x.sbr
|
||||
|
||||
$(OBJD)\edll2x.obj : edll2x.cpp
|
||||
|
||||
$(BIND)\edll2x$(DETOURS_BITS).dll : $(OBJD)\edll2x.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
|
||||
$(OBJD)\edll2x.obj /LD \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console \
|
||||
/base:$(EDLL2X_BASE)
|
||||
|
||||
$(OBJD)\edll2x$(DETOURS_BITS).bsc : $(OBJD)\edll2x.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\edll2x.sbr
|
||||
|
||||
$(OBJD)\edll3x.obj : edll3x.cpp
|
||||
|
||||
$(BIND)\edll3x$(DETOURS_BITS).dll : $(OBJD)\edll3x.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb \
|
||||
$(OBJD)\edll3x.obj /LD \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console \
|
||||
/base:$(EDLL3X_BASE)
|
||||
|
||||
$(OBJD)\edll3x$(DETOURS_BITS).bsc : $(OBJD)\edll3x.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\edll3x.sbr
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\edll1x$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\edll1x$(DETOURS_OPTION_BITS).pdb:
|
||||
$(OPTD)\edll2x$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\edll2x$(DETOURS_OPTION_BITS).pdb:
|
||||
$(OPTD)\edll3x$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\edll3x$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\edll1x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll1x$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\edll1x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll1x$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\edll2x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll2x$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\edll2x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll2x$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\edll3x$(DETOURS_OPTION_BITS).dll : $(OPTD)\edll3x$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\edll3x$(DETOURS_OPTION_BITS).pdb : $(OPTD)\edll3x$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\edll1x$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\edll1x$(DETOURS_OPTION_BITS).pdb \
|
||||
$(BIND)\edll2x$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\edll2x$(DETOURS_OPTION_BITS).pdb \
|
||||
$(BIND)\edll3x$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\edll3x$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
$(BIND)\einst.exe
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (edll1x.cpp of edll1x.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////// DLL Stuff
|
||||
//
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
DETOUR_SECTION_RECORD record;
|
||||
CHAR szMessage[32];
|
||||
};
|
||||
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The First Dll!"
|
||||
};
|
||||
#pragma data_seg()
|
||||
|
||||
__declspec(dllexport) VOID WINAPI EDll1Function(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__declspec(dllexport) ULONG WINAPI
|
||||
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)dwReason;
|
||||
(void)lpReserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (edll2x.cpp of einst.exe/edll2x.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////// DLL Stuff
|
||||
//
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
DETOUR_SECTION_RECORD record;
|
||||
CHAR szMessage[32];
|
||||
};
|
||||
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Second Dll!"
|
||||
};
|
||||
#pragma data_seg()
|
||||
|
||||
__declspec(dllexport) VOID WINAPI EDll2Function(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__declspec(dllexport) ULONG WINAPI
|
||||
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)dwReason;
|
||||
(void)lpReserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (edll3x.cpp of einst.exe/edll3x.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////// DLL Stuff
|
||||
//
|
||||
struct CPrivateStuffPart1
|
||||
{
|
||||
DETOUR_SECTION_RECORD header;
|
||||
CHAR szMessage[48];
|
||||
};
|
||||
|
||||
struct CPrivateStuffPart2
|
||||
{
|
||||
DETOUR_SECTION_RECORD header;
|
||||
CHAR szMessage[64];
|
||||
};
|
||||
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
CPrivateStuffPart1 record1;
|
||||
CPrivateStuffPart2 record2;
|
||||
};
|
||||
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
{
|
||||
sizeof(CPrivateStuffPart1),
|
||||
0,
|
||||
{ /* d9ab8a41-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a41,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Third DLL Part One!"
|
||||
},
|
||||
{
|
||||
{
|
||||
sizeof(CPrivateStuffPart2),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Third DLL Part Two!"
|
||||
}
|
||||
};
|
||||
#pragma data_seg()
|
||||
|
||||
__declspec(dllexport) VOID WINAPI EDll3Function(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__declspec(dllexport) ULONG WINAPI
|
||||
DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID lpReserved)
|
||||
{
|
||||
(void)hInstance;
|
||||
(void)dwReason;
|
||||
(void)lpReserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (einst.cpp of einst.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
struct CPrivateStuff
|
||||
{
|
||||
DETOUR_SECTION_HEADER header;
|
||||
DETOUR_SECTION_RECORD record;
|
||||
CHAR szMessage[32];
|
||||
};
|
||||
|
||||
#ifdef INCLUDE_THIS
|
||||
#pragma data_seg(".detour")
|
||||
|
||||
static CPrivateStuff private_stuff = {
|
||||
DETOUR_SECTION_HEADER_DECLARE(sizeof(CPrivateStuff)),
|
||||
{
|
||||
(sizeof(CPrivateStuff) - sizeof(DETOUR_SECTION_HEADER)),
|
||||
0,
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
}
|
||||
},
|
||||
"The Application!"
|
||||
};
|
||||
#pragma data_seg()
|
||||
#endif
|
||||
|
||||
GUID my_guid =
|
||||
{ /* d9ab8a40-f4cc-11d1-b6d7-006097b010e3 */
|
||||
0xd9ab8a40,
|
||||
0xf4cc,
|
||||
0x11d1,
|
||||
{0xb6, 0xd7, 0x00, 0x60, 0x97, 0xb0, 0x10, 0xe3}
|
||||
};
|
||||
|
||||
__declspec(dllimport) VOID WINAPI EDll1Function(VOID);
|
||||
__declspec(dllimport) VOID WINAPI EDll2Function(VOID);
|
||||
__declspec(dllimport) VOID WINAPI EDll3Function(VOID);
|
||||
|
||||
void FindPayload(HINSTANCE hinst)
|
||||
{
|
||||
CHAR szModuleName[256];
|
||||
GetModuleFileNameA(hinst, szModuleName, ARRAYSIZE(szModuleName));
|
||||
printf(" %p : %s\n", hinst, szModuleName);
|
||||
|
||||
ULONG cbData = 0;
|
||||
PBYTE pbData = (PBYTE)DetourFindPayload(hinst, my_guid, &cbData);
|
||||
|
||||
if (pbData) {
|
||||
printf(" %08p..%08p : %50.50s\n",
|
||||
pbData,
|
||||
pbData + cbData,
|
||||
pbData);
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
(void)hinst;
|
||||
(void)hprev;
|
||||
(void)lpszCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
printf("Source .EXE:\n");
|
||||
FindPayload(NULL);
|
||||
printf("\n");
|
||||
|
||||
printf("DLL and EXE binaries loaded:\n");
|
||||
|
||||
EDll1Function();
|
||||
EDll2Function();
|
||||
EDll3Function();
|
||||
|
||||
for (HINSTANCE hiter = NULL; (hiter = DetourEnumerateModules(hiter)) != NULL;) {
|
||||
FindPayload(hiter);
|
||||
}
|
||||
|
||||
if ((PVOID)hinst == (PVOID)lpszCmdLine) {
|
||||
DispatchMessage(NULL); // Force load of gdi32.dll
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\excep.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\excep.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\excep.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\excep.obj : excep.cpp
|
||||
$(OBJD)\firstexc.obj : firstexc.cpp
|
||||
|
||||
$(BIND)\excep.exe : $(OBJD)\excep.obj $(OBJD)\firstexc.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\excep.obj $(OBJD)\firstexc.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console /entry:WinMainCRTStartup
|
||||
|
||||
$(OBJD)\excep.bsc : $(OBJD)\excep.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\excep.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\excep.exe
|
||||
$(BIND)\excep.exe
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// First Chance Exception Handling Test Program (excep.cpp of excep.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// For more information on exception handling, see "A Crash Course on the
|
||||
// Depths of Win32 Structured Exception Handling," by Matt Pietrek in the
|
||||
// January 1997 issue of Microsoft Systems Journal.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
#include "firstexc.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static LPVOID s_pvData = NULL;
|
||||
static DWORD s_dwDataPerm = 0;
|
||||
|
||||
static LONG ExceptCatch(LONG nTry, DWORD dwException, LPEXCEPTION_POINTERS pinfo)
|
||||
{
|
||||
printf(" ExceptCatch(%ld, %08lx, %08lx)\n", nTry, dwException, (ULONG)pinfo);
|
||||
#ifdef INCLUDE_THIS
|
||||
if (nTry == 0) {
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
#endif
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
static int BadCode(int nTry)
|
||||
{
|
||||
printf(" BadCode(Try:%d)\n", nTry);
|
||||
printf(" BadCode -> %ld\n", *(PULONG)s_pvData);
|
||||
((PULONG)s_pvData)[0] = 0;
|
||||
printf(" BadCode -> %ld\n", *(PULONG)s_pvData);
|
||||
((PULONG)s_pvData)[-1] = 0;
|
||||
printf(" BadCode -> %ld\n", *(PULONG)s_pvData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void safe(int nTry)
|
||||
{
|
||||
__try {
|
||||
printf(" try(%d)\n", nTry);
|
||||
BadCode(nTry);
|
||||
printf(" good(%d)\n", nTry);
|
||||
} __except(ExceptCatch(nTry,
|
||||
GetExceptionCode(),
|
||||
GetExceptionInformation())) {
|
||||
DWORD dwExcept = GetExceptionCode();
|
||||
|
||||
printf(" handler(%d) : %08lx\n", nTry, dwExcept);
|
||||
}
|
||||
}
|
||||
|
||||
void raw(int nTry)
|
||||
{
|
||||
BadCode(nTry);
|
||||
}
|
||||
|
||||
LONG WINAPI MyVirtualFaultFilter(PEXCEPTION_POINTERS pException)
|
||||
{
|
||||
PEXCEPTION_RECORD pExceptRec = pException->ExceptionRecord;
|
||||
|
||||
if (pExceptRec->ExceptionCode == 0xc0000005) {
|
||||
printf("-- Memory access exception.\n");
|
||||
if (pExceptRec->NumberParameters >= 2 &&
|
||||
pExceptRec->ExceptionInformation[1] >= (ULONG)s_pvData &&
|
||||
pExceptRec->ExceptionInformation[1] <= (ULONG)s_pvData + sizeof(ULONG)) {
|
||||
|
||||
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READWRITE, &s_dwDataPerm);
|
||||
printf("-- Changed permissions.\n");
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
(void)hinst;
|
||||
(void)hprev;
|
||||
(void)lpszCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
s_pvData = VirtualAlloc(NULL, sizeof(ULONG), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
if (s_pvData == NULL) {
|
||||
printf("VirtualAlloc failed: %ld\n", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
*(PULONG)s_pvData = 1;
|
||||
|
||||
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READONLY, &s_dwDataPerm);
|
||||
|
||||
DetourFirstChanceExceptionFilter(MyVirtualFaultFilter);
|
||||
|
||||
printf("main\n");
|
||||
printf("--------------------------------------------------\n");
|
||||
int nTry = 0;
|
||||
for (; nTry < 1; nTry++) {
|
||||
// safe(nTry);
|
||||
}
|
||||
printf("-- safe ------------------------------------------\n");
|
||||
safe(nTry);
|
||||
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READWRITE, &s_dwDataPerm);
|
||||
*(PULONG)s_pvData = 1;
|
||||
VirtualProtect(s_pvData, sizeof(ULONG), PAGE_READONLY, &s_dwDataPerm);
|
||||
|
||||
printf("-- raw -------------------------------------------\n");
|
||||
printf("*\n");
|
||||
printf("* NB: The second attempt to write will fail because it isn't handled.\n");
|
||||
printf("*\n");
|
||||
raw(nTry);
|
||||
printf("--------------------------------------------------\n");
|
||||
printf("exit\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (firstexc.cpp of firstexc.lib)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// For more information on exception handling, see "A Crash Course on the
|
||||
// Depths of Win32 Structured Exception Handling," by Matt Pietrek in the
|
||||
// January 1997 issue of Microsoft Systems Journal.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
#include "firstexc.h"
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma warning(disable: 4740)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static BOOL s_bExceptionDetourInstalled = FALSE;
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER s_pFirstChanceFilter = NULL;
|
||||
|
||||
ULONG (NTAPI *Real_NtContinue)(IN PCONTEXT ContextRecord,
|
||||
IN BOOLEAN TestAlerts) = NULL;
|
||||
|
||||
VOID (NTAPI *Real_KiUserExceptionDispatcher)(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT ContextFrame) = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This function effectively removes all try..catch frames for the current
|
||||
// stack. It forces all exceptions to be treated as unhandled exceptions.
|
||||
//
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4733)
|
||||
static VOID WINAPI RemoveAllExceptionHandlers(VOID)
|
||||
{
|
||||
// The basic, OS defined exception frame
|
||||
struct EXCEPTION_REGISTRATION
|
||||
{
|
||||
EXCEPTION_REGISTRATION* prev;
|
||||
FARPROC handler;
|
||||
};
|
||||
|
||||
EXCEPTION_REGISTRATION * pVCExcRec = NULL;
|
||||
EXCEPTION_REGISTRATION * pLastGood = NULL;
|
||||
|
||||
__asm mov eax, FS:[0];
|
||||
__asm mov [pVCExcRec], eax;
|
||||
|
||||
for (pLastGood = pVCExcRec; (ULONG)pVCExcRec != ~0ul; ) {
|
||||
if ((ULONG)pVCExcRec >= 0x30000000)
|
||||
break;
|
||||
|
||||
pLastGood = pVCExcRec;
|
||||
pVCExcRec = (EXCEPTION_REGISTRATION *)(pVCExcRec->prev);
|
||||
}
|
||||
|
||||
__asm mov eax, [pLastGood];
|
||||
__asm mov FS:[0], eax;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Routine Description:
|
||||
//
|
||||
// This routine is entered on return from kernel mode to dispatch a user
|
||||
// mode exception. If a frame based handler handles the exception, then
|
||||
// the execution is continued. Else last chance processing is performed.
|
||||
//
|
||||
// NOTE: This procedure is not called, but rather dispatched to.
|
||||
// It depends on there not being a return address on the stack
|
||||
// (assumption w.r.t. argument offsets.)
|
||||
//
|
||||
// Arguments:
|
||||
// ExceptionRecord (esp+0) - Supplies a pointer to an exception record.
|
||||
// ContextRecord (esp+4) - Supplies a pointer to a context frame.
|
||||
//
|
||||
// Return Value:
|
||||
// None.
|
||||
//
|
||||
static VOID __declspec(naked) NTAPI
|
||||
Detour_KiUserExceptionDispatcher(PEXCEPTION_RECORD pExceptRec,
|
||||
CONTEXT *pContext)
|
||||
{
|
||||
__asm {
|
||||
xor eax, eax ; // Create fake return address on stack.
|
||||
push eax ; // (Generally, we are called by the kernel.)
|
||||
|
||||
push ebp ; // Prolog
|
||||
mov ebp, esp ;
|
||||
sub esp, __LOCAL_SIZE ;
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER pFirstChanceFilter;
|
||||
EXCEPTION_POINTERS ep;
|
||||
DWORD dwReturn;
|
||||
DWORD dwError;
|
||||
|
||||
ep.ExceptionRecord = pExceptRec;
|
||||
ep.ContextRecord = pContext;
|
||||
pFirstChanceFilter = s_pFirstChanceFilter;
|
||||
dwReturn = EXCEPTION_CONTINUE_SEARCH;
|
||||
dwError = 0;
|
||||
|
||||
if (s_pFirstChanceFilter) {
|
||||
dwReturn = pFirstChanceFilter(&ep);
|
||||
}
|
||||
|
||||
if (dwReturn == EXCEPTION_CONTINUE_EXECUTION) {
|
||||
dwError = Real_NtContinue(pContext, 0);
|
||||
// This call should *NEVER* return. If it does, we want to fail to the debugger.
|
||||
RemoveAllExceptionHandlers();
|
||||
}
|
||||
|
||||
if (dwReturn == EXCEPTION_EXECUTE_HANDLER) { // Special: Call debugger.
|
||||
RemoveAllExceptionHandlers();
|
||||
}
|
||||
|
||||
__asm {
|
||||
mov ebx, pExceptRec ;
|
||||
mov ecx, pContext ;
|
||||
push ecx ;
|
||||
push ebx ;
|
||||
mov eax, [Real_KiUserExceptionDispatcher];
|
||||
jmp eax ;
|
||||
;
|
||||
; The above code should never return.
|
||||
;
|
||||
int 3 ; // Break!
|
||||
;
|
||||
mov esp, ebp ; // Epilog
|
||||
pop ebp ;
|
||||
ret ;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Set the first-chance exception filter.
|
||||
//
|
||||
// Returns the pointer to the last first-chance exception filter if there
|
||||
// was one. If this is the first first-chance exception filter, installs
|
||||
// the necessary detour and acquires the appropriate function pointers.
|
||||
// If the parameter is NULL, first-chance exception filtering is disabled.
|
||||
//
|
||||
// A first-chance exception filter should always return one of three
|
||||
// possible codes:
|
||||
//
|
||||
// EXCEPTION_CONTINUE_SEARCH:
|
||||
// The exception was not handled by this filter; continue the
|
||||
// search for the appropriate exception handler.
|
||||
//
|
||||
// EXCEPTION_CONTINUE_EXECUTION:
|
||||
// The exception was handled by this filter; continue execution
|
||||
// at the point were the exception was thrown.
|
||||
//
|
||||
// EXCEPTION_EXECUTE_HANDLER:
|
||||
// Drastic failure in the exception filter. Process the
|
||||
// exception as if no exception handlers were installed.
|
||||
// (i.e. Give the user a chance to invoke the debugger.)
|
||||
//
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
|
||||
DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER pNewFirstChanceFilter)
|
||||
{
|
||||
if (!s_bExceptionDetourInstalled) {
|
||||
s_bExceptionDetourInstalled = TRUE;
|
||||
|
||||
Real_NtContinue = (ULONG (NTAPI *)(IN PCONTEXT, IN BOOLEAN))
|
||||
DetourFindFunction("ntdll.dll", "NtContinue");
|
||||
Real_KiUserExceptionDispatcher =
|
||||
(VOID (NTAPI *)(IN PEXCEPTION_RECORD, IN PCONTEXT))
|
||||
DetourFindFunction("ntdll.dll", "KiUserExceptionDispatcher");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)Real_KiUserExceptionDispatcher,
|
||||
Detour_KiUserExceptionDispatcher);
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER pOldFirstChanceFilter = s_pFirstChanceFilter;
|
||||
s_pFirstChanceFilter = pNewFirstChanceFilter;
|
||||
return pOldFirstChanceFilter;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (firstexc.h of firstexc.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef _FIRSTEXC_H_
|
||||
#define _FIRSTEXC_H_
|
||||
|
||||
/////////////////////////////////////////////// First Chance Exception Filter.
|
||||
//
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
|
||||
DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelFilter);
|
||||
|
||||
#endif // _FIRSTEXC_H_
|
||||
//
|
||||
//////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Program to test DetourFindFunction.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
# ARM64 does not like base addresses below 4GB.
|
||||
# Append two extra zeros for it.
|
||||
#
|
||||
!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
|
||||
TARGET_BASE=0x190000000
|
||||
EXTEND_BASE=0x1a0000000
|
||||
!else
|
||||
TARGET_BASE=0x1900000
|
||||
EXTEND_BASE=0x1a00000
|
||||
!endif
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\target$(DETOURS_BITS).dll \
|
||||
$(BIND)\extend$(DETOURS_BITS).dll \
|
||||
$(BIND)\findfunc.exe \
|
||||
$(BIND)\symtest.exe \
|
||||
$(BIND)\dbghelp.dll \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\target$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\extend$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\findfunc.bsc \
|
||||
$(OBJD)\symtest.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\target.obj : target.cpp
|
||||
|
||||
$(OBJD)\target.res : target.rc
|
||||
|
||||
$(BIND)\target$(DETOURS_BITS).dll $(BIND)\target$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\target.obj $(OBJD)\target.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\target.obj $(OBJD)\target.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:Target \
|
||||
/base:$(TARGET_BASE) \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\target$(DETOURS_BITS).bsc : $(OBJD)\target.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\target.sbr
|
||||
|
||||
$(OBJD)\extend.obj : extend.cpp
|
||||
|
||||
$(OBJD)\extend.res : extend.rc
|
||||
|
||||
$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\extend$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\extend.obj $(OBJD)\extend.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\extend.obj $(OBJD)\extend.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/base:$(EXTEND_BASE) \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\extend$(DETOURS_BITS).bsc : $(OBJD)\extend.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\extend.sbr
|
||||
|
||||
$(OBJD)\findfunc.obj : findfunc.cpp
|
||||
|
||||
$(BIND)\findfunc.exe : $(OBJD)\findfunc.obj $(BIND)\target$(DETOURS_BITS).lib $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\findfunc.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no $(BIND)\target$(DETOURS_BITS).lib
|
||||
|
||||
$(OBJD)\findfunc.bsc : $(OBJD)\findfunc.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\findfunc.sbr
|
||||
|
||||
$(OBJD)\symtest.obj : symtest.cpp
|
||||
|
||||
$(BIND)\symtest.exe : $(OBJD)\symtest.obj $(BIND)\target$(DETOURS_BITS).lib $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\symtest.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no $(BIND)\target$(DETOURS_BITS).lib
|
||||
|
||||
$(OBJD)\symtest.bsc : $(OBJD)\symtest.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\symtest.sbr
|
||||
|
||||
# We try to get the 64-bit dbghelp first because it is a lot more useful.
|
||||
$(BIND)\dbghelp.dll : {"$(PROGRAMFILES)\Debugging Tools for Windows 64-bit";$(PATH)}dbghelp.dll
|
||||
-copy $** $(BIND)\dbghelp.dll
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\target*.* $(BIND)\extend*.* 2>nul
|
||||
-del $(BIND)\findfunc.* $(BIND)\symtest.* $(BIND)\dbghelp.dll 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\extend$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\extend$(DETOURS_OPTION_BITS).pdb:
|
||||
$(OPTD)\target$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\target$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\extend$(DETOURS_OPTION_BITS).dll : $(OPTD)\extend$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\extend$(DETOURS_OPTION_BITS).pdb : $(OPTD)\extend$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\target$(DETOURS_OPTION_BITS).dll : $(OPTD)\target$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\target$(DETOURS_OPTION_BITS).pdb : $(OPTD)\target$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\extend$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\extend$(DETOURS_OPTION_BITS).pdb \
|
||||
$(BIND)\target$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\target$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
verbose: all
|
||||
cls
|
||||
$(BIND)\symtest.exe
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\findfunc.exe
|
||||
@echo.
|
||||
@echo -------- Should not load extend$(DETOURS_BITS).dll--------------------------------------
|
||||
$(BIND)\findfunc.exe
|
||||
@echo.
|
||||
@echo -------- Adding extend$(DETOURS_BITS).dll to findfunc.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\findfunc.exe
|
||||
@echo.
|
||||
@echo -------- Should load extend$(DETOURS_BITS).dll statically ------------------------------
|
||||
$(BIND)\findfunc.exe
|
||||
@echo.
|
||||
@echo -------- Removing extend$(DETOURS_BITS).dll from findfunc.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\findfunc.exe
|
||||
@echo.
|
||||
@echo -------- Should not load extend$(DETOURS_BITS).dll -------------------------------------
|
||||
$(BIND)\findfunc.exe
|
||||
@echo.
|
||||
@echo -------- Should load extend$(DETOURS_BITS).dll dynamically using withdll.exe -----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\findfunc.exe
|
||||
@echo.
|
||||
@echo -------- Should list symbols using symtest.exe -----------
|
||||
$(BIND)\symtest.exe
|
||||
@echo.
|
||||
@echo -------- Test completed. ------------------------------------------------
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (extend.cpp of extend.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// An example dynamically detouring a function.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
|
||||
static LONG nExtends = 0;
|
||||
static LONG nInterns = 0;
|
||||
|
||||
static DWORD (WINAPI * TrueTarget)(DWORD dwCount) = NULL;
|
||||
static DWORD (WINAPI * TrueHidden)(DWORD dwCount) = NULL;
|
||||
static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
|
||||
|
||||
// Extend is a detour for Target.
|
||||
static DWORD WINAPI Extend(DWORD dwCount)
|
||||
{
|
||||
InterlockedIncrement(&nExtends);
|
||||
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Extend (%ld) -> %ld.\n", dwCount, dwCount + 1000);
|
||||
dwCount = TrueTarget(dwCount + 1000);
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Extend (.....) -> %ld.\n", dwCount);
|
||||
return dwCount;
|
||||
}
|
||||
|
||||
// Intern is a detour for Hidden.
|
||||
static DWORD WINAPI Intern(DWORD dwCount)
|
||||
{
|
||||
InterlockedIncrement(&nInterns);
|
||||
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Intern (%ld) -> %ld.\n", dwCount, dwCount + 10);
|
||||
dwCount = TrueHidden(dwCount + 10);
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Intern (.....) -> %ld.\n", dwCount);
|
||||
return dwCount;
|
||||
}
|
||||
|
||||
static int WINAPI ExtendEntryPoint()
|
||||
{
|
||||
// We couldn't call LoadLibrary in DllMain, so our functions here.
|
||||
LONG error;
|
||||
|
||||
// We separate out the functions in the export table (Target)
|
||||
// from the ones that require debug symbols (Hidden).
|
||||
TrueTarget =
|
||||
(DWORD (WINAPI *)(DWORD))
|
||||
DetourFindFunction("target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll", "Target");
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueTarget, Extend);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured Target().\n");
|
||||
}
|
||||
else {
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring Target(): %ld\n", error);
|
||||
}
|
||||
|
||||
// Now try to detour the functions requiring debug symbols.
|
||||
TrueHidden =
|
||||
(DWORD (WINAPI *)(DWORD))
|
||||
DetourFindFunction("target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll", "Hidden");
|
||||
if (TrueHidden == NULL) {
|
||||
error = GetLastError();
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: TrueHidden = %p (error = %ld)\n", TrueHidden, error);
|
||||
}
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueHidden, Intern);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured Hidden().\n");
|
||||
}
|
||||
else {
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring Hidden(): %ld\n", error);
|
||||
}
|
||||
|
||||
// Now let the application start executing.
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Calling EntryPoint\n");
|
||||
fflush(stdout);
|
||||
|
||||
return TrueEntryPoint();
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
// NB: DllMain can't call LoadLibrary, so we hook the app entry point.
|
||||
|
||||
TrueEntryPoint = (int (WINAPI *)())DetourGetEntryPoint(NULL);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured EntryPoint().\n");
|
||||
}
|
||||
else {
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring EntryPoint(): %ld\n", error);
|
||||
}
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
// Detach functions found from the export table.
|
||||
if (TrueTarget != NULL) {
|
||||
DetourDetach(&(PVOID&)TrueTarget, (PVOID)Extend);
|
||||
}
|
||||
|
||||
// Detach functions found from debug symbols.
|
||||
if (TrueHidden != NULL) {
|
||||
DetourDetach(&(PVOID&)TrueHidden, (PVOID)Intern);
|
||||
}
|
||||
|
||||
// Detach the entry point.
|
||||
DetourDetach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Removed Target() detours (%ld), %ld/%ld calls.\n",
|
||||
error, nExtends, nInterns);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for extend.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Dyanmic Interception Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (findfunc.cpp of findfunc.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <detours.h>
|
||||
#include "target.h"
|
||||
|
||||
int __cdecl main(void)
|
||||
{
|
||||
printf("findfunc.exe: Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
printf("DLLs:\n");
|
||||
for (HMODULE hModule = NULL; (hModule = DetourEnumerateModules(hModule)) != NULL;) {
|
||||
CHAR szName[MAX_PATH] = { 0 };
|
||||
GetModuleFileNameA(hModule, szName, sizeof(szName) - 1);
|
||||
printf(" %p: %s\n", hModule, szName);
|
||||
}
|
||||
|
||||
DWORD dwCount = 10000;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
printf("findfunc.exe: Calling (%ld).\n", dwCount);
|
||||
dwCount = Target(dwCount) + 10000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,385 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (symtest.cpp of symtest.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
#include <detours.h>
|
||||
#include "target.h"
|
||||
|
||||
#if (_MSC_VER < 1299)
|
||||
#include <imagehlp.h>
|
||||
typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
|
||||
typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
|
||||
typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
|
||||
typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
|
||||
#else
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4091) // empty typedef
|
||||
#include <dbghelp.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion);
|
||||
|
||||
typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess,
|
||||
IN LPCSTR UserSearchPath,
|
||||
IN BOOL fInvadeProcess);
|
||||
typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions);
|
||||
typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
|
||||
typedef DWORD64 (NTAPI *PF_SymLoadModule64)(IN HANDLE hProcess,
|
||||
IN HANDLE hFile,
|
||||
IN PSTR ImageName,
|
||||
IN PSTR ModuleName,
|
||||
IN DWORD64 BaseOfDll,
|
||||
IN DWORD SizeOfDll);
|
||||
typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(IN HANDLE hProcess,
|
||||
IN DWORD64 qwAddr,
|
||||
OUT PIMAGEHLP_MODULE64 ModuleInfo);
|
||||
typedef BOOL (NTAPI *PF_SymFromName)(IN HANDLE hProcess,
|
||||
IN LPSTR Name,
|
||||
OUT PSYMBOL_INFO Symbol);
|
||||
#if (_MSC_VER < 1299)
|
||||
typedef BOOL (NTAPI *PF_SymRegisterCallback64)();
|
||||
typedef BOOL (NTAPI *PF_SymEnumerateModules64)();
|
||||
typedef BOOL (NTAPI *PF_SymEnumSymbols)();
|
||||
#else
|
||||
typedef BOOL (NTAPI *PF_SymRegisterCallback64)(IN HANDLE hProcess,
|
||||
IN PSYMBOL_REGISTERED_CALLBACK64
|
||||
CallbackFunction,
|
||||
IN ULONG64 UserContext);
|
||||
typedef BOOL (NTAPI *PF_SymEnumerateModules64)(IN HANDLE hProcess,
|
||||
IN PSYM_ENUMMODULES_CALLBACK64
|
||||
EnumModulesCallback,
|
||||
IN PVOID UserContext);
|
||||
typedef BOOL (NTAPI *PF_SymEnumSymbols)(IN HANDLE hProcess,
|
||||
IN ULONG64 BaseOfDll,
|
||||
IN PCSTR Mask,
|
||||
IN PSYM_ENUMERATESYMBOLS_CALLBACK
|
||||
EnumSymbolsCallback,
|
||||
IN PVOID UserContext);
|
||||
#endif
|
||||
|
||||
PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx = NULL;
|
||||
PF_SymInitialize pfSymInitialize = NULL;
|
||||
PF_SymSetOptions pfSymSetOptions = NULL;
|
||||
PF_SymGetOptions pfSymGetOptions = NULL;
|
||||
PF_SymLoadModule64 pfSymLoadModule64 = NULL;
|
||||
PF_SymGetModuleInfo64 pfSymGetModuleInfo64 = NULL;
|
||||
PF_SymFromName pfSymFromName = NULL;
|
||||
PF_SymRegisterCallback64 pfSymRegisterCallback64 = NULL;
|
||||
PF_SymEnumerateModules64 pfSymEnumerateModules64 = NULL;
|
||||
PF_SymEnumSymbols pfSymEnumSymbols = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
#if (_MSC_VER > 1299)
|
||||
static BOOL WINAPI SymEnumerateCallback(
|
||||
PCSTR pszModule,
|
||||
DWORD64 base,
|
||||
PVOID pvUserContext)
|
||||
{
|
||||
(void)pvUserContext;
|
||||
printf(" %p: %s\n", (PVOID)base, pszModule);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int nSymbolCount = 0;
|
||||
static BOOL WINAPI SymEnumerateSymbols(PSYMBOL_INFO pSym,
|
||||
ULONG size,
|
||||
PVOID pvUserContext)
|
||||
{
|
||||
(void)size;
|
||||
(void)pvUserContext;
|
||||
if (strstr(pSym->Name, "Target") != NULL ||
|
||||
strstr(pSym->Name, "Hidden") != NULL) {
|
||||
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
|
||||
nSymbolCount++;
|
||||
}
|
||||
else if (nSymbolCount < 5) {
|
||||
printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
|
||||
nSymbolCount++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void truncate(PCHAR data)
|
||||
{
|
||||
size_t len = strlen(data);
|
||||
if (len > 0 && data[len-1] == '\r') {
|
||||
data[--len] = '\0';
|
||||
}
|
||||
if (len > 0 && data[len-1] == '\n') {
|
||||
data[--len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI CallbackFunction(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 context)
|
||||
{
|
||||
(void)context;
|
||||
|
||||
switch (action) {
|
||||
case CBA_DEBUG_INFO:
|
||||
truncate((PCHAR)data);
|
||||
printf("::> %s\n", (PCHAR)data);
|
||||
return TRUE;
|
||||
|
||||
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
|
||||
printf("::> proc=%p action=%08lx data=%p\n",
|
||||
(PVOID)hProcess,
|
||||
action,
|
||||
(PVOID)data);
|
||||
{
|
||||
PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 pi = (PIMAGEHLP_DEFERRED_SYMBOL_LOAD64)data;
|
||||
printf("pi->SizeOfStruct = %ld\n", pi->SizeOfStruct);
|
||||
printf("pi->BaseOfImage = %p\n", (PVOID)(size_t)pi->BaseOfImage);
|
||||
printf("pi->CheckSum = %8lx\n", pi->CheckSum);
|
||||
printf("pi->FileName = %p [%s]\n", pi->FileName, pi->FileName);
|
||||
printf("pi->Reparse = %d\n", pi->Reparse);
|
||||
}
|
||||
return FALSE;
|
||||
default:
|
||||
printf("::> proc=%p action=%08lx data=%p\n",
|
||||
(PVOID)hProcess,
|
||||
action,
|
||||
(PVOID)data);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int __cdecl main(void)
|
||||
{
|
||||
printf("symtest.exe: Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
//////////////////////////////////////////////////////// Get the functions.
|
||||
//
|
||||
HMODULE hDbgHelp = LoadLibraryA("dbghelp.dll");
|
||||
if (hDbgHelp == NULL) {
|
||||
printf("Couldn't load dbghelp.dll");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pfImagehlpApiVersionEx
|
||||
= (PF_ImagehlpApiVersionEx)GetProcAddress(hDbgHelp,
|
||||
"ImagehlpApiVersionEx");
|
||||
pfSymInitialize
|
||||
= (PF_SymInitialize)GetProcAddress(hDbgHelp, "SymInitialize");
|
||||
pfSymSetOptions
|
||||
= (PF_SymSetOptions)GetProcAddress(hDbgHelp, "SymSetOptions");
|
||||
pfSymGetOptions
|
||||
= (PF_SymGetOptions)GetProcAddress(hDbgHelp, "SymGetOptions");
|
||||
pfSymLoadModule64
|
||||
= (PF_SymLoadModule64)GetProcAddress(hDbgHelp, "SymLoadModule64");
|
||||
pfSymGetModuleInfo64
|
||||
= (PF_SymGetModuleInfo64)GetProcAddress(hDbgHelp, "SymGetModuleInfo64");
|
||||
pfSymFromName
|
||||
= (PF_SymFromName)GetProcAddress(hDbgHelp, "SymFromName");
|
||||
pfSymRegisterCallback64
|
||||
= (PF_SymRegisterCallback64)GetProcAddress(hDbgHelp, "SymRegisterCallback64");
|
||||
pfSymEnumerateModules64
|
||||
= (PF_SymEnumerateModules64)GetProcAddress(hDbgHelp, "SymEnumerateModules64");
|
||||
pfSymEnumSymbols
|
||||
= (PF_SymEnumSymbols)GetProcAddress(hDbgHelp, "SymEnumSymbols");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
API_VERSION av;
|
||||
ZeroMemory(&av, sizeof(av));
|
||||
av.MajorVersion = API_VERSION_NUMBER;
|
||||
|
||||
pfImagehlpApiVersionEx(&av);
|
||||
printf(" Version: %d.%d (%d)\n",
|
||||
av.MajorVersion,
|
||||
av.MinorVersion,
|
||||
API_VERSION_NUMBER);
|
||||
|
||||
if (!pfSymInitialize(hProcess, NULL, FALSE)) {
|
||||
printf("SymInitialize failed: %ld\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if (_MSC_VER > 1299)
|
||||
pfSymRegisterCallback64(hProcess, CallbackFunction, NULL);
|
||||
#endif
|
||||
|
||||
DWORD dw = pfSymGetOptions();
|
||||
printf("GetOptions = %08lx\n", dw);
|
||||
dw &= ~(SYMOPT_CASE_INSENSITIVE |
|
||||
SYMOPT_UNDNAME |
|
||||
SYMOPT_DEFERRED_LOADS |
|
||||
0);
|
||||
dw |= (
|
||||
#if defined(SYMOPT_EXACT_SYMBOLS)
|
||||
SYMOPT_EXACT_SYMBOLS |
|
||||
#endif
|
||||
#if defined(SYMOPT_DEBUG)
|
||||
SYMOPT_DEBUG |
|
||||
#endif
|
||||
#if defined(SYMOPT_NO_UNQUALIFIED_LOADS)
|
||||
SYMOPT_NO_UNQUALIFIED_LOADS |
|
||||
#endif
|
||||
#if defined(SYMOPT_FAIL_CRITICAL_ERRORS)
|
||||
SYMOPT_FAIL_CRITICAL_ERRORS |
|
||||
#endif
|
||||
#if defined(SYMOPT_INCLUDE_32BIT_MODULES)
|
||||
SYMOPT_INCLUDE_32BIT_MODULES |
|
||||
#endif
|
||||
0);
|
||||
printf("SetOptions = %08lx\n", dw);
|
||||
pfSymSetOptions(dw);
|
||||
|
||||
/////////////////////////////////////////////// First, try GetProcAddress.
|
||||
//
|
||||
PCHAR pszFile = "target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll";
|
||||
HMODULE hModule = LoadLibraryA(pszFile);
|
||||
if (hModule == NULL) {
|
||||
printf("LoadLibraryA(%s) failed: %ld\n", pszFile, GetLastError());
|
||||
return 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////// Then try ImageHelp.
|
||||
//
|
||||
#if (_MSC_VER > 1299)
|
||||
|
||||
//CHAR szFull[MAX_PATH];
|
||||
//GetModuleFileNameA(hModule, szFull, sizeof(szFull));
|
||||
printf("SymLoadModule64(%s) will be called.\n", pszFile /*szFull*/);
|
||||
DWORD64 loaded = pfSymLoadModule64(hProcess, NULL,
|
||||
(PCHAR)pszFile/*szFull*/, NULL,
|
||||
(DWORD64)hModule, 0);
|
||||
if (loaded == 0) {
|
||||
printf("SymLoadModule64(%p) failed: %ld\n", hProcess, GetLastError());
|
||||
printf("\n");
|
||||
}
|
||||
else {
|
||||
printf("SymLoadModule64(%p) succeeded: 0x%p\n", hProcess, (PVOID)loaded);
|
||||
}
|
||||
|
||||
CHAR szModName[512];
|
||||
|
||||
printf("Modules:\n");
|
||||
// The first parameter of PSYM_ENUMMODULES_CALLBACK64 changed from PSTR to PCSTR
|
||||
// between Windows 2003 and Windows 7. Cast here to work with either.
|
||||
pfSymEnumerateModules64(hProcess, (PSYM_ENUMMODULES_CALLBACK64)SymEnumerateCallback, NULL);
|
||||
printf("\n");
|
||||
|
||||
IMAGEHLP_MODULE64 modinfo;
|
||||
ZeroMemory(&modinfo, sizeof(modinfo));
|
||||
modinfo.SizeOfStruct = sizeof(modinfo);
|
||||
if (!pfSymGetModuleInfo64(hProcess, (DWORD64)hModule, &modinfo)) {
|
||||
printf("SymGetModuleInfo64(%p, %p) [64] failed: %ld\n",
|
||||
hProcess, hModule, GetLastError());
|
||||
}
|
||||
else {
|
||||
printf("SymGetModuleInfo64(%p, %p) [64] succeeded: %ld\n",
|
||||
hProcess, hModule, GetLastError());
|
||||
StringCchCopyA(szModName, ARRAYSIZE(szModName), modinfo.ModuleName);
|
||||
StringCchCatA(szModName, ARRAYSIZE(szModName), "!");
|
||||
|
||||
printf("NumSyms: %ld\n", modinfo.NumSyms);
|
||||
printf("SymType: %d\n", modinfo.SymType);
|
||||
printf("ModuleName: %s\n", modinfo.ModuleName);
|
||||
printf("ImageName: %s\n", modinfo.ImageName);
|
||||
printf("LoadedImageName: %s\n", modinfo.LoadedImageName);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
printf("DLLs:\n");
|
||||
for (hModule = NULL; (hModule = DetourEnumerateModules(hModule)) != NULL;) {
|
||||
CHAR szName[MAX_PATH];
|
||||
GetModuleFileNameA(hModule, szName, sizeof(szName));
|
||||
printf(" %p: %s\n", hModule, szName);
|
||||
}
|
||||
|
||||
if (pfSymEnumSymbols == NULL) {
|
||||
printf("Couldn't find SymEnumSymbols.\n");
|
||||
}
|
||||
else {
|
||||
printf("===Enum===\n");
|
||||
SetLastError(0);
|
||||
nSymbolCount = 0;
|
||||
if (!pfSymEnumSymbols(hProcess, loaded, NULL, SymEnumerateSymbols, NULL)) {
|
||||
printf("SymEnumSymbols() failed: %ld\n",
|
||||
GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
// Look for specific symbols.
|
||||
struct CFullSymbol : SYMBOL_INFO {
|
||||
CHAR szRestOfName[MAX_SYM_NAME];
|
||||
} symbol;
|
||||
CHAR szFullName[512];
|
||||
|
||||
// Look for Target
|
||||
StringCchCopyA(szFullName, ARRAYSIZE(szFullName), szModName);
|
||||
StringCchCatA(szFullName, ARRAYSIZE(szFullName), "Target");
|
||||
printf("Symbol: [%s]\n", szFullName);
|
||||
|
||||
ZeroMemory(&symbol, sizeof(symbol));
|
||||
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
#ifdef DBHLPAPI
|
||||
symbol.MaxNameLen = MAX_SYM_NAME;
|
||||
#else
|
||||
symbol.MaxNameLength = MAX_SYM_NAME;
|
||||
#endif
|
||||
|
||||
SetLastError(0);
|
||||
if (!pfSymFromName(hProcess, szFullName, &symbol)) {
|
||||
printf("--SymFromName(%s) failed: %ld\n", szFullName, GetLastError());
|
||||
}
|
||||
if (symbol.Address != 0) {
|
||||
printf("--SymFromName(%s) succeeded\n", szFullName);
|
||||
}
|
||||
|
||||
printf("%s => %p\n\n", szFullName, (PBYTE)symbol.Address);
|
||||
|
||||
// Look for Hidden
|
||||
StringCchCopyA(szFullName, ARRAYSIZE(szFullName), szModName);
|
||||
StringCchCatA(szFullName, ARRAYSIZE(szFullName), "Hidden");
|
||||
printf("Symbol: [%s]\n", szFullName);
|
||||
|
||||
ZeroMemory(&symbol, sizeof(symbol));
|
||||
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
#ifdef DBHLPAPI
|
||||
symbol.MaxNameLen = MAX_SYM_NAME;
|
||||
#else
|
||||
symbol.MaxNameLength = MAX_SYM_NAME;
|
||||
#endif
|
||||
|
||||
SetLastError(0);
|
||||
if (!pfSymFromName(hProcess, szFullName, &symbol)) {
|
||||
printf("--SymFromName(%s) failed: %ld\n", szFullName, GetLastError());
|
||||
}
|
||||
if (symbol.Address != 0) {
|
||||
printf("--SymFromName(%s) succeeded\n", szFullName);
|
||||
}
|
||||
|
||||
printf("%s => %p\n\n", szFullName, (PBYTE)symbol.Address);
|
||||
#endif
|
||||
|
||||
// We call Target once to insure it is loaded.
|
||||
Target(0);
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (target.cpp of target.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "target.h"
|
||||
|
||||
extern "C" DWORD WINAPI Hidden(DWORD dwCount)
|
||||
{
|
||||
printf("target.dll: Hidden(%ld) -> %ld.\n", dwCount, dwCount + 1);
|
||||
return dwCount + 1;
|
||||
}
|
||||
|
||||
// We use this point to ensure Hidden isn't inlined.
|
||||
static DWORD (WINAPI * SelfHidden)(DWORD dwCount) = Hidden;
|
||||
|
||||
DWORD WINAPI Target(DWORD dwCount)
|
||||
{
|
||||
printf("target.dll: Target (%ld) -> %ld.\n", dwCount, dwCount + 100);
|
||||
dwCount = SelfHidden(dwCount + 100);
|
||||
printf("target.dll: Target (.....) -> %ld.\n", dwCount);
|
||||
return dwCount;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
(void)hinst;
|
||||
(void)dwReason;
|
||||
(void)reserved;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detour Test Program (target.h of target.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
DWORD WINAPI Target(DWORD dwCount);
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for target.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\impmunge.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\impmunge.bsc
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ test.exe.* 2>nul
|
||||
-del $(BIND)\impmunge.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\impmunge.obj : impmunge.cpp
|
||||
|
||||
$(BIND)\impmunge.exe : $(OBJD)\impmunge.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\impmunge.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) imagehlp.lib /subsystem:console
|
||||
|
||||
$(OBJD)\impmunge.bsc : $(OBJD)\impmunge.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\impmunge.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\impmunge.exe
|
||||
$(BIND)\impmunge.exe /m /o:test.exe.1 $(BIND)\impmunge.exe
|
||||
$(BIND)\impmunge.exe /m /l- /o:test.exe.2 test.exe.1
|
||||
$(BIND)\impmunge.exe /m /l- /o:test.exe.3 test.exe.2
|
||||
$(BIND)\impmunge.exe /m /l- /o:test.exe.4 test.exe.3
|
||||
$(BIND)\impmunge.exe /l test.exe.4
|
||||
$(BIND)\impmunge.exe /r /l- /o:test.exe.0 test.exe.4
|
||||
$(BIND)\impmunge.exe /l test.exe.0
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,464 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (impmunge.cpp of impmunge.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#include <detours.h>
|
||||
#pragma warning(disable:4091) // empty typedef
|
||||
#include <imagehlp.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
////////////////////////////////////////////////////////////// Error Messages.
|
||||
//
|
||||
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
|
||||
{
|
||||
printf("ASSERT(%s) failed in %s, line %ld.", szMsg, szFile, nLine);
|
||||
}
|
||||
|
||||
#define ASSERT(x) \
|
||||
do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
|
||||
;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static BOOLEAN s_fRestore = FALSE;
|
||||
static BOOLEAN s_fList = TRUE;
|
||||
static BOOLEAN s_fMunge = FALSE;
|
||||
static BOOLEAN s_fToSymbols = FALSE;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static BOOL CALLBACK ListByway(_In_opt_ PVOID pContext,
|
||||
_In_opt_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)ppszOutFile;
|
||||
|
||||
printf(" byway -------------------------------- %s\n", pszFile ? pszFile : "");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ListFile(_In_opt_ PVOID pContext,
|
||||
_In_ LPCSTR pszOrigFile,
|
||||
_In_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)ppszOutFile;
|
||||
|
||||
printf(" file %-32.32s %-32.32s\n",
|
||||
pszOrigFile ? pszOrigFile : "",
|
||||
pszFile ? pszFile : "");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ListSymbol(_In_opt_ PVOID pContext,
|
||||
_In_ ULONG nOrigOrdinal,
|
||||
_In_ ULONG nOrdinal,
|
||||
_Out_ ULONG *pnOutOrdinal,
|
||||
_In_opt_ LPCSTR pszOrigSymbol,
|
||||
_In_opt_ LPCSTR pszSymbol,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)pnOutOrdinal;
|
||||
(void)ppszOutSymbol;
|
||||
|
||||
char szOrig[80];
|
||||
char szLast[80];
|
||||
|
||||
if (pszOrigSymbol == NULL) {
|
||||
StringCchPrintfA(szOrig, sizeof(szOrig), "#%d", nOrigOrdinal);
|
||||
pszOrigSymbol = szOrig;
|
||||
}
|
||||
if (pszSymbol == NULL) {
|
||||
StringCchPrintfA(szLast, sizeof(szLast), "#%d", nOrdinal);
|
||||
pszSymbol = szLast;
|
||||
}
|
||||
|
||||
printf(" symbol %-32.32s %-32.32s\n", pszOrigSymbol, pszSymbol);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ListCommit(PVOID pContext)
|
||||
{
|
||||
(void)pContext;
|
||||
|
||||
printf(" commit\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct MUNGE_STATE
|
||||
{
|
||||
BOOL fLastWasByway;
|
||||
LONG nBywayCount;
|
||||
CHAR szBuffer[512];
|
||||
};
|
||||
|
||||
static BOOL CALLBACK MungeByway(_In_opt_ PVOID pContext,
|
||||
_In_opt_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
|
||||
|
||||
printf("|");
|
||||
|
||||
if (pState->fLastWasByway) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pState->fLastWasByway = TRUE;
|
||||
|
||||
if (pszFile == NULL) {
|
||||
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mb_munge_%d.dll", pState->nBywayCount++);
|
||||
*ppszOutFile = pState->szBuffer;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK MungeFile(_In_opt_ PVOID pContext,
|
||||
_In_ LPCSTR pszOrigFile,
|
||||
_In_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pszOrigFile;
|
||||
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
|
||||
|
||||
pState->fLastWasByway = FALSE;
|
||||
|
||||
printf("*");
|
||||
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mf_%s", pszFile);
|
||||
*ppszOutFile = pState->szBuffer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK MungeSymbol(_In_opt_ PVOID pContext,
|
||||
_In_ ULONG nOrigOrdinal,
|
||||
_In_ ULONG nOrdinal,
|
||||
_Out_ ULONG *pnOutOrdinal,
|
||||
_In_opt_ LPCSTR pszOrigSymbol,
|
||||
_In_opt_ LPCSTR pszSymbol,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
|
||||
{
|
||||
(void)nOrigOrdinal;
|
||||
(void)pszOrigSymbol;
|
||||
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
|
||||
|
||||
pState->fLastWasByway = FALSE;
|
||||
|
||||
printf(".");
|
||||
if (nOrdinal != 0) {
|
||||
if (s_fToSymbols) {
|
||||
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mo_%d", (int)nOrdinal);
|
||||
*pnOutOrdinal = 0;
|
||||
*ppszOutSymbol = pState->szBuffer;
|
||||
}
|
||||
else {
|
||||
*pnOutOrdinal = 10000 + nOrdinal;
|
||||
*ppszOutSymbol = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "ms_%s", pszSymbol);
|
||||
*pnOutOrdinal = 0;
|
||||
*ppszOutSymbol = pState->szBuffer;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK MungeCommit(PVOID pContext)
|
||||
{
|
||||
MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
|
||||
|
||||
pState->fLastWasByway = FALSE;
|
||||
|
||||
printf("\n");
|
||||
(void)pContext;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static BOOL CALLBACK RestoreByway(_In_opt_ PVOID pContext,
|
||||
_In_opt_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)pszFile;
|
||||
|
||||
*ppszOutFile = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK RestoreFile(_In_opt_ PVOID pContext,
|
||||
_In_ LPCSTR pszOrigFile,
|
||||
_In_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)pszFile;
|
||||
|
||||
*ppszOutFile = pszOrigFile;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK RestoreSymbol(_In_opt_ PVOID pContext,
|
||||
_In_ ULONG nOrigOrdinal,
|
||||
_In_ ULONG nOrdinal,
|
||||
_Out_ ULONG *pnOutOrdinal,
|
||||
_In_opt_ LPCSTR pszOrigSymbol,
|
||||
_In_opt_ LPCSTR pszSymbol,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)nOrdinal;
|
||||
(void)pszSymbol;
|
||||
|
||||
*pnOutOrdinal = nOrigOrdinal;
|
||||
*ppszOutSymbol = pszOrigSymbol;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK RestoreCommit(PVOID pContext)
|
||||
{
|
||||
(void)pContext;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
BOOL EditFile(PCHAR pszInput, PCHAR pszOutput)
|
||||
{
|
||||
BOOL fGood = TRUE;
|
||||
|
||||
HANDLE hOld = INVALID_HANDLE_VALUE;
|
||||
HANDLE hNew = INVALID_HANDLE_VALUE;
|
||||
PDETOUR_BINARY pBinary = NULL;
|
||||
|
||||
if (pszOutput != NULL) {
|
||||
printf("%s -> %s:\n", pszInput, pszOutput);
|
||||
}
|
||||
else {
|
||||
printf("%s:\n", pszInput);
|
||||
}
|
||||
|
||||
hOld = CreateFileA(pszInput,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (hOld == INVALID_HANDLE_VALUE) {
|
||||
printf("Couldn't open input file: %s, error: %ld\n",
|
||||
pszInput, GetLastError());
|
||||
fGood = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
|
||||
printf("DetourBinaryOpen failed: %ld\n", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (hOld != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hOld);
|
||||
hOld = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (s_fRestore) {
|
||||
if (!DetourBinaryEditImports(pBinary,
|
||||
NULL,
|
||||
RestoreByway,
|
||||
RestoreFile,
|
||||
RestoreSymbol,
|
||||
RestoreCommit)) {
|
||||
|
||||
printf("DetourBinaryEditImports for munge failed: %ld\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (s_fMunge) {
|
||||
MUNGE_STATE state;
|
||||
state.fLastWasByway = FALSE;
|
||||
state.nBywayCount = 1;
|
||||
|
||||
if (!DetourBinaryEditImports(pBinary,
|
||||
&state,
|
||||
MungeByway,
|
||||
MungeFile,
|
||||
MungeSymbol,
|
||||
MungeCommit)) {
|
||||
|
||||
printf("DetourBinaryEditImports for munge failed: %ld\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (s_fList) {
|
||||
if (!DetourBinaryEditImports(pBinary,
|
||||
NULL,
|
||||
ListByway,
|
||||
ListFile,
|
||||
ListSymbol,
|
||||
ListCommit)) {
|
||||
|
||||
printf("DetourBinaryEditImports for list failed: %ld\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (pszOutput != NULL) {
|
||||
hNew = CreateFileA(pszOutput,
|
||||
GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (hNew == INVALID_HANDLE_VALUE) {
|
||||
printf("Couldn't open output file: %s, error: %ld\n",
|
||||
pszOutput, GetLastError());
|
||||
fGood = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!DetourBinaryWrite(pBinary, hNew)) {
|
||||
printf("DetourBinaryWrite failed: %ld\n", GetLastError());
|
||||
fGood = FALSE;
|
||||
}
|
||||
|
||||
CloseHandle(hNew);
|
||||
hNew = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
DetourBinaryClose(pBinary);
|
||||
pBinary = NULL;
|
||||
|
||||
|
||||
if (fGood && pszOutput != NULL) {
|
||||
if (!BindImageEx(BIND_NO_BOUND_IMPORTS, pszOutput, ".", ".", NULL)) {
|
||||
printf("Warning: Couldn't bind binary %s: %ld\n", pszOutput, GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (pBinary) {
|
||||
DetourBinaryClose(pBinary);
|
||||
pBinary = NULL;
|
||||
}
|
||||
if (hNew != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hNew);
|
||||
hNew = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (hOld != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hOld);
|
||||
hOld = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return fGood;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void PrintUsage(void)
|
||||
{
|
||||
printf("Usage:\n"
|
||||
" impmunge [options] binary_files\n"
|
||||
"Options:\n"
|
||||
" /l : List imports.\n"
|
||||
" /l- : Don't list imports.\n"
|
||||
" /m : Munge imports.\n"
|
||||
" /r : Remove import munges.\n"
|
||||
" /o:file : Set name of output file; must be include with /m or /r.\n"
|
||||
" /? : This help screen.\n");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////// main.
|
||||
//
|
||||
int CDECL main(int argc, char **argv)
|
||||
{
|
||||
BOOL fNeedHelp = FALSE;
|
||||
PCHAR pszOutput = NULL;
|
||||
|
||||
int arg = 1;
|
||||
for (; arg < argc && !fNeedHelp; arg++) {
|
||||
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
|
||||
CHAR *argn = argv[arg] + 1;
|
||||
CHAR *argp = argn;
|
||||
while (*argp && *argp != ':')
|
||||
argp++;
|
||||
if (*argp == ':')
|
||||
*argp++ = '\0';
|
||||
|
||||
switch (argn[0]) {
|
||||
|
||||
case 'l': // List contents of import table.
|
||||
case 'L':
|
||||
s_fList = (argn[1] != '-');
|
||||
break;
|
||||
|
||||
case 'm': // Munge import table.
|
||||
case 'M':
|
||||
s_fMunge = (argn[1] != '-');
|
||||
break;
|
||||
|
||||
case 'o': // Set output file name.
|
||||
case 'O':
|
||||
pszOutput = argp;
|
||||
break;
|
||||
case 'r': // Restore file to unmunged state.
|
||||
case 'R':
|
||||
s_fRestore = (argn[1] != '-');
|
||||
break;
|
||||
|
||||
case 's': // Munge ordinals to symbols
|
||||
case 'S':
|
||||
s_fToSymbols = true;
|
||||
break;
|
||||
|
||||
case '?': // Help
|
||||
fNeedHelp = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
fNeedHelp = TRUE;
|
||||
printf("Bad argument: %s:%s\n", argn, argp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!s_fList && !s_fMunge && !s_fRestore) {
|
||||
fNeedHelp = TRUE;
|
||||
break;
|
||||
}
|
||||
if (pszOutput == NULL && (s_fMunge || s_fRestore)) {
|
||||
fNeedHelp = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
EditFile(argv[arg], pszOutput);
|
||||
pszOutput = NULL;
|
||||
}
|
||||
}
|
||||
if (argc == 1) {
|
||||
fNeedHelp = TRUE;
|
||||
}
|
||||
if (fNeedHelp) {
|
||||
PrintUsage();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// End of File
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\member.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\member.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2> nul
|
||||
-del $(BIND)\member.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\member.obj : member.cpp
|
||||
|
||||
$(BIND)\member.exe : $(OBJD)\member.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\member.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console
|
||||
|
||||
$(OBJD)\member.bsc : $(OBJD)\member.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\member.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\member.exe
|
||||
@echo.
|
||||
$(BIND)\member.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test a detour of a member function (member.cpp of member.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// By default, C++ member functions use the __thiscall calling convention.
|
||||
// In order to Detour a member function, both the trampoline and the detour
|
||||
// must have exactly the same calling convention as the target function.
|
||||
// Unfortunately, the VC compiler does not support a __thiscall, so the only
|
||||
// way to create legal detour and trampoline functions is by making them
|
||||
// class members of a "detour" class.
|
||||
//
|
||||
// In addition, C++ does not support converting a pointer to a member
|
||||
// function to an arbitrary pointer. To get a raw pointer, the address of
|
||||
// the member function must be moved into a temporary member-function
|
||||
// pointer, then passed by taking it's address, then de-referencing it.
|
||||
// Fortunately, the compiler will optimize the code to remove the extra
|
||||
// pointer operations.
|
||||
//
|
||||
// If X::Target is a virtual function, the following code will *NOT* work
|
||||
// because &X::Target is the address of a thunk that does a virtual call,
|
||||
// not the real address of the X::Target. You can get the real address
|
||||
// of X::Target by looking directly in the VTBL for class X, but there
|
||||
// is no legal way to 1) get the address of X's VTBL or 2) get the offset
|
||||
// of ::Target within that VTBL. You can of course, figure these out for
|
||||
// a particular class and function, but there is no general way to do so.
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
#include "..\slept\verify.cpp"
|
||||
|
||||
//////////////////////////////////////////////////////////////// Target Class.
|
||||
//
|
||||
class CMember
|
||||
{
|
||||
public:
|
||||
void Target(void);
|
||||
};
|
||||
|
||||
void CMember::Target(void)
|
||||
{
|
||||
printf(" CMember::Target! (this:%p)\n", this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////// Detour Class.
|
||||
//
|
||||
class CDetour /* add ": public CMember" to enable access to member variables... */
|
||||
{
|
||||
public:
|
||||
void Mine_Target(void);
|
||||
static void (CDetour::* Real_Target)(void);
|
||||
|
||||
// Class shouldn't have any member variables or virtual functions.
|
||||
};
|
||||
|
||||
void CDetour::Mine_Target(void)
|
||||
{
|
||||
printf(" CDetour::Mine_Target! (this:%p)\n", this);
|
||||
(this->*Real_Target)();
|
||||
}
|
||||
|
||||
void (CDetour::* CDetour::Real_Target)(void) = (void (CDetour::*)(void))&CMember::Target;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void (CMember::* pfTarget)(void) = &CMember::Target;
|
||||
void (CDetour::* pfMine)(void) = &CDetour::Mine_Target;
|
||||
|
||||
Verify("CMember::Target ", *(PBYTE*)&pfTarget);
|
||||
Verify("*CDetour::Real_Target", *(PBYTE*)&CDetour::Real_Target);
|
||||
Verify("CDetour::Mine_Target ", *(PBYTE*)&pfMine);
|
||||
|
||||
printf("\n");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&)CDetour::Real_Target,
|
||||
*(PBYTE*)&pfMine);
|
||||
|
||||
LONG l = DetourTransactionCommit();
|
||||
printf("DetourTransactionCommit = %ld\n", l);
|
||||
printf("\n");
|
||||
|
||||
Verify("CMember::Target ", *(PBYTE*)&pfTarget);
|
||||
Verify("*CDetour::Real_Target", *(&(PBYTE&)CDetour::Real_Target));
|
||||
Verify("CDetour::Mine_Target ", *(PBYTE*)&pfMine);
|
||||
printf("\n");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
CMember target;
|
||||
|
||||
printf("Calling CMember (w/o Detour):\n");
|
||||
(((CDetour*)&target)->*CDetour::Real_Target)();
|
||||
|
||||
printf("Calling CMember (will be detoured):\n");
|
||||
target.Target();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
######################################################################
|
||||
##
|
||||
## Hook test for glFinish
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib gdi32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\ogldet$(DETOURS_BITS).dll \
|
||||
$(BIND)\testogl.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\ogldet$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\testogl.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\ogldet.obj : ogldet.cpp
|
||||
|
||||
$(OBJD)\ogldet.res : ogldet.rc
|
||||
|
||||
$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\ogldet$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\ogldet.obj $(OBJD)\ogldet.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\ogldet.obj $(OBJD)\ogldet.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:hookedGlFinish \
|
||||
$(LIBS) opengl32.lib
|
||||
|
||||
$(OBJD)\ogldet$(DETOURS_BITS).bsc : $(OBJD)\ogldet.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\ogldet.sbr
|
||||
|
||||
$(OBJD)\testogl.obj : testogl.cpp
|
||||
|
||||
$(BIND)\testogl.exe : $(OBJD)\testogl.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\testogl.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) opengl32.lib \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\testogl.bsc : $(OBJD)\testogl.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\testogl.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\ogldet*.* 2>nul
|
||||
-del $(BIND)\testogl.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\olgdet$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\olgdet$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).dll : $(OPTD)\olgdet$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).pdb : $(OPTD)\olgdet$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\olgdet$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. ---------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should not load ogldet$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Adding ogldet$(DETOURS_BITS).dll to testogl.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should load ogldet$(DETOURS_BITS).dll statically ----------------------------
|
||||
$(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Removing ogldet$(DETOURS_BITS).dll from testogl.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should not load ogldet$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\testogl.exe
|
||||
@echo.
|
||||
@echo -------- Should load ogldet$(DETOURS_BITS).dll dynamically using withdll.exe----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\ogldet$(DETOURS_BITS).dll $(BIND)\testogl.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module: ogldet.dll
|
||||
//
|
||||
// This DLL is based on the sample simple.dll. A detour is inserted for
|
||||
// the OpenGL glFinish function.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include "detours.h"
|
||||
|
||||
static void (WINAPI * trueGlFinish)(void) = glFinish;
|
||||
|
||||
void WINAPI hookedGlFinish(void)
|
||||
{
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" hookedGlFinish Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
trueGlFinish();
|
||||
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" hookedGlFinish done.\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)trueGlFinish, hookedGlFinish);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured glFinish().\n");
|
||||
}
|
||||
else {
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring glFinish(): %d\n", error);
|
||||
}
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)trueGlFinish, hookedGlFinish);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Removed detour glFinish() (result=%d)\n", error);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for ogldet.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "ogldet" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "ogldet" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Open GL Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// File: testogl.cpp
|
||||
// Module: testogl.exe (oglsimple.dll)
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
int __cdecl main()
|
||||
{
|
||||
printf("testogl.exe: Starting\n");
|
||||
fflush(stdout);
|
||||
|
||||
glFinish();
|
||||
|
||||
printf("testogl.exe: done\n");
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
CFLAGS=$(CFLAGS) /EHsc
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\payload.exe \
|
||||
$(BIND)\payloadtarget.exe
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\payload.* 2>nul
|
||||
-del $(BIND)\payloadtarget.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\payload.obj : payload.cpp
|
||||
|
||||
$(BIND)\payload.exe : $(OBJD)\payload.obj $(DEPS)
|
||||
link\
|
||||
/SUBSYSTEM:CONSOLE\
|
||||
$(LINKFLAGS)\
|
||||
$(LIBS)\
|
||||
/PDB:"$(@R).pdb"\
|
||||
/OUT:"$@"\
|
||||
$**\
|
||||
|
||||
$(OBJD)\payloadtarget.obj : payloadtarget.cpp
|
||||
|
||||
$(BIND)\payloadtarget.exe : $(OBJD)\payloadtarget.obj $(DEPS)
|
||||
link\
|
||||
/SUBSYSTEM:CONSOLE\
|
||||
$(LINKFLAGS)\
|
||||
$(LIBS)\
|
||||
/PDB:"$(@R).pdb"\
|
||||
/OUT:"$@"\
|
||||
$**\
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\payload.exe $(BIND)\payloadtarget.exe
|
||||
$(BIND)\payload.exe
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
#include "payloadguid.hpp"
|
||||
|
||||
HANDLE hChildProcess = NULL;
|
||||
HANDLE hChildThread = NULL;
|
||||
|
||||
__declspec(noreturn) void HandleApiFailure(const char* api)
|
||||
{
|
||||
DWORD lastErr = GetLastError();
|
||||
std::cout << "payload.exe: " << api << " failed (" << lastErr << ')' << std::endl;
|
||||
|
||||
if (hChildThread != NULL)
|
||||
{
|
||||
CloseHandle(hChildThread);
|
||||
}
|
||||
|
||||
if (hChildProcess != NULL)
|
||||
{
|
||||
TerminateProcess(hChildProcess, 1);
|
||||
CloseHandle(hChildProcess);
|
||||
}
|
||||
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
std::wstring GetProcessFileName(HANDLE process)
|
||||
{
|
||||
DWORD exeLocation_size = MAX_PATH + 1;
|
||||
|
||||
std::wstring exeLocation;
|
||||
exeLocation.resize(exeLocation_size);
|
||||
|
||||
if (!QueryFullProcessImageNameW(process, 0, &exeLocation[0], &exeLocation_size))
|
||||
{
|
||||
HandleApiFailure("QueryFullProcessImageNameW");
|
||||
}
|
||||
|
||||
exeLocation.resize(exeLocation_size);
|
||||
return exeLocation;
|
||||
}
|
||||
|
||||
void StartChild()
|
||||
{
|
||||
std::wstring target = GetProcessFileName(GetCurrentProcess());
|
||||
target.erase(target.rfind(L'\\') + 1);
|
||||
target += L"payloadtarget.exe";
|
||||
|
||||
STARTUPINFOW si = { sizeof(si) };
|
||||
PROCESS_INFORMATION pi;
|
||||
if (!CreateProcessW(target.c_str(), NULL, NULL, NULL, false,
|
||||
CREATE_SUSPENDED, NULL, NULL, &si, &pi))
|
||||
{
|
||||
HandleApiFailure("CreateProcessW");
|
||||
}
|
||||
|
||||
hChildProcess = pi.hProcess;
|
||||
hChildThread = pi.hThread;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
volatile T* InjectPayload(HANDLE hProcess, T payload, REFGUID guid)
|
||||
{
|
||||
return static_cast<volatile T*>(
|
||||
DetourCopyPayloadToProcessEx(hProcess,guid, &payload, sizeof(payload)));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
StartChild();
|
||||
|
||||
// give the child a handle to ourself
|
||||
HANDLE targetHandleToParent;
|
||||
if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
|
||||
hChildProcess, &targetHandleToParent, 0, false, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
HandleApiFailure("DuplicateHandle");
|
||||
}
|
||||
|
||||
if (!InjectPayload(hChildProcess, targetHandleToParent, PARENT_HANDLE_PAYLOAD))
|
||||
{
|
||||
HandleApiFailure("DetourCopyPayloadToProcessEx");
|
||||
}
|
||||
|
||||
// inject a payload in ourself containing zero data
|
||||
// the goal is for the child process to find this payload
|
||||
// and fill it with random data, to test DetourFindRemotePayload
|
||||
volatile random_payload_t* payloadAddr =
|
||||
InjectPayload<random_payload_t>(GetCurrentProcess(), 0, RANDOM_DATA_PAYLOAD);
|
||||
if (!payloadAddr)
|
||||
{
|
||||
HandleApiFailure("DetourCopyPayloadToProcessEx");
|
||||
}
|
||||
|
||||
if (!ResumeThread(hChildThread))
|
||||
{
|
||||
HandleApiFailure("ResumeThread");
|
||||
}
|
||||
|
||||
CloseHandle(hChildThread);
|
||||
hChildThread = NULL;
|
||||
|
||||
if (WaitForSingleObject(hChildProcess, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
HandleApiFailure("WaitForSingleObject");
|
||||
}
|
||||
|
||||
DWORD exitCode;
|
||||
if (!GetExitCodeProcess(hChildProcess, &exitCode))
|
||||
{
|
||||
HandleApiFailure("GetExitCodeProcess");
|
||||
}
|
||||
|
||||
// the exit code should match the random data the child process gave us
|
||||
random_payload_t payload = *payloadAddr;
|
||||
if (exitCode == payload)
|
||||
{
|
||||
std::cout << "Success, exit code (0x" << std::uppercase << std::hex << exitCode
|
||||
<< ") matches payload content (0x" << payload << ')' << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error, exit code (0x" << std::uppercase << std::hex << exitCode
|
||||
<< ") does not matches payload content (0x" << payload << ')' << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
#include <guiddef.h>
|
||||
|
||||
// {C2569A74-12FE-4E06-8F02-8DF13E39A266}
|
||||
const GUID PARENT_HANDLE_PAYLOAD =
|
||||
{ 0xc2569a74, 0x12fe, 0x4e06, { 0x8f, 0x2, 0x8d, 0xf1, 0x3e, 0x39, 0xa2, 0x66 } };
|
||||
|
||||
// {CB5230ED-04FA-4C47-B606-AC09B2777601}
|
||||
const GUID RANDOM_DATA_PAYLOAD =
|
||||
{ 0xcb5230ed, 0x4fa, 0x4c47, { 0xb6, 0x6, 0xac, 0x9, 0xb2, 0x77, 0x76, 0x1 } };
|
||||
|
||||
typedef unsigned int random_payload_t;
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
#define _CRT_RAND_S
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
#include "payloadguid.hpp"
|
||||
|
||||
HANDLE hParent = NULL;
|
||||
|
||||
__declspec(noreturn) void HandleApiFailure(const char* api)
|
||||
{
|
||||
DWORD lastErr = GetLastError();
|
||||
std::cout << "payloadtarget.exe: " << api << " failed (" << lastErr << ')' << std::endl;
|
||||
|
||||
if (hParent)
|
||||
{
|
||||
CloseHandle(hParent);
|
||||
}
|
||||
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
DWORD payloadSize;
|
||||
void* payloadAddr = DetourFindPayloadEx(PARENT_HANDLE_PAYLOAD, &payloadSize);
|
||||
if (!payloadAddr || payloadSize != sizeof(HANDLE))
|
||||
{
|
||||
HandleApiFailure("DetourFindPayloadEx");
|
||||
}
|
||||
|
||||
hParent = *static_cast<HANDLE*>(payloadAddr);
|
||||
|
||||
DWORD randomPayloadSize;
|
||||
void* randomPayload = DetourFindRemotePayload(hParent, RANDOM_DATA_PAYLOAD, &randomPayloadSize);
|
||||
if (!randomPayload || randomPayloadSize != sizeof(random_payload_t))
|
||||
{
|
||||
HandleApiFailure("DetourFindRemotePayload");
|
||||
}
|
||||
|
||||
random_payload_t randomData;
|
||||
if (rand_s(&randomData) != 0)
|
||||
{
|
||||
HandleApiFailure("rand_s");
|
||||
}
|
||||
|
||||
|
||||
if (!WriteProcessMemory(hParent, randomPayload, &randomData, sizeof(randomData), NULL))
|
||||
{
|
||||
HandleApiFailure("WriteProcessMemory");
|
||||
}
|
||||
|
||||
CloseHandle(hParent);
|
||||
hParent = NULL;
|
||||
|
||||
// conversion to int return type is potentially undefined
|
||||
ExitProcess(randomData);
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\region.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\region.bsc
|
||||
!ENDIF
|
||||
|
||||
clean:
|
||||
-del *~ 2> nul
|
||||
-del $(BIND)\region.* 2> nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\region.obj : region.cpp
|
||||
|
||||
$(BIND)\region.exe : $(OBJD)\region.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\region.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console
|
||||
|
||||
$(OBJD)\region.bsc : $(OBJD)\region.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\region.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\region.exe
|
||||
@echo.
|
||||
$(BIND)\region.exe
|
||||
@echo.
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test the different system region bounds (region.cpp of region.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
|
||||
|
||||
DWORD WINAPI LoudSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
DWORD dwBeg = GetTickCount();
|
||||
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
DWORD dwEnd = GetTickCount();
|
||||
|
||||
printf("Slept %lu ticks.\n", dwEnd - dwBeg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
PVOID AttachAndDetach(DWORD dwMilliseconds)
|
||||
{
|
||||
LONG error;
|
||||
PVOID trampoline;
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueSleepEx, LoudSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("Attach: %ld, Trampoline: %p\n", error, TrueSleepEx);
|
||||
|
||||
trampoline = TrueSleepEx;
|
||||
|
||||
printf("\n");
|
||||
printf("Sleep(%lu)\n", dwMilliseconds);
|
||||
Sleep(dwMilliseconds);
|
||||
printf("\n");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)TrueSleepEx, LoudSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
return trampoline;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
// First, save the default system region.
|
||||
|
||||
PVOID pDefaultLower = DetourSetSystemRegionLowerBound(NULL);
|
||||
PVOID pDefaultUpper = DetourSetSystemRegionUpperBound(NULL);
|
||||
|
||||
// Now attach the detour with the default system region.
|
||||
|
||||
DetourSetSystemRegionLowerBound(pDefaultLower);
|
||||
DetourSetSystemRegionUpperBound(pDefaultUpper);
|
||||
|
||||
printf("%p..%p: ", pDefaultLower, pDefaultUpper);
|
||||
PVOID pTramp1 = AttachAndDetach(10);
|
||||
|
||||
printf("%p..%p: ", pDefaultLower, pDefaultUpper);
|
||||
PVOID pTramp2 = AttachAndDetach(10);
|
||||
|
||||
// Now attach the detour with a smaller system region.
|
||||
|
||||
PVOID pSmallerLower = (PVOID)( ((ULONG_PTR)pTramp1) & ~(ULONG_PTR)0x3fffffff );
|
||||
PVOID pSmallerUpper = (PVOID)( ((ULONG_PTR)pTramp1 + 0x3fffffff) & ~(ULONG_PTR)0x3fffffff );
|
||||
|
||||
DetourSetSystemRegionLowerBound(pSmallerLower);
|
||||
DetourSetSystemRegionUpperBound(pSmallerUpper);
|
||||
|
||||
printf("%p..%p: ", pSmallerLower, pSmallerUpper);
|
||||
PVOID pTramp3 = AttachAndDetach(20);
|
||||
|
||||
printf("Sleep(30)\n");
|
||||
Sleep(30);
|
||||
printf("\n");
|
||||
|
||||
if (pTramp1 != pTramp2) {
|
||||
printf("!!!!!! Trampoling allocation is not deterministic. %p != %p\n", pTramp1, pTramp2);
|
||||
return 1;
|
||||
}
|
||||
else if (pTramp2 == pTramp3) {
|
||||
printf("!!!!!! Trampoling allocation doesn't skip region. %p == %p\n", pTramp2, pTramp3);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\setdll.exe \
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\setdll.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\setdll.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\setdll.obj : setdll.cpp
|
||||
|
||||
$(BIND)\setdll.exe : $(OBJD)\setdll.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\setdll.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) /subsystem:console
|
||||
|
||||
$(OBJD)\setdll.bsc : $(OBJD)\setdll.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\setdll.sbr
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
option:
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (setdll.cpp of setdll.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <detours.h>
|
||||
#pragma warning(push)
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable:6102 6103) // /analyze warnings
|
||||
#endif
|
||||
#include <strsafe.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
////////////////////////////////////////////////////////////// Error Messages.
|
||||
//
|
||||
VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
|
||||
{
|
||||
printf("ASSERT(%s) failed in %s, line %ld.", szMsg, szFile, nLine);
|
||||
}
|
||||
|
||||
#define ASSERT(x) \
|
||||
do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
|
||||
;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static BOOLEAN s_fRemove = FALSE;
|
||||
static CHAR s_szDllPath[MAX_PATH] = "";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This code verifies that the named DLL has been configured correctly
|
||||
// to be imported into the target process. DLLs must export a function with
|
||||
// ordinal #1 so that the import table touch-up magic works.
|
||||
//
|
||||
static BOOL CALLBACK ExportCallback(_In_opt_ PVOID pContext,
|
||||
_In_ ULONG nOrdinal,
|
||||
_In_opt_ LPCSTR pszName,
|
||||
_In_opt_ PVOID pCode)
|
||||
{
|
||||
(void)pContext;
|
||||
(void)pCode;
|
||||
(void)pszName;
|
||||
|
||||
if (nOrdinal == 1) {
|
||||
*((BOOL *)pContext) = TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DoesDllExportOrdinal1(PCHAR pszDllPath)
|
||||
{
|
||||
HMODULE hDll = LoadLibraryExA(pszDllPath, NULL, DONT_RESOLVE_DLL_REFERENCES);
|
||||
if (hDll == NULL) {
|
||||
printf("setdll.exe: LoadLibraryEx(%s) failed with error %ld.\n",
|
||||
pszDllPath,
|
||||
GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL validFlag = FALSE;
|
||||
DetourEnumerateExports(hDll, &validFlag, ExportCallback);
|
||||
FreeLibrary(hDll);
|
||||
return validFlag;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static BOOL CALLBACK ListBywayCallback(_In_opt_ PVOID pContext,
|
||||
_In_opt_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pContext;
|
||||
|
||||
*ppszOutFile = pszFile;
|
||||
if (pszFile) {
|
||||
printf(" %s\n", pszFile);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ListFileCallback(_In_opt_ PVOID pContext,
|
||||
_In_ LPCSTR pszOrigFile,
|
||||
_In_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
(void)pContext;
|
||||
|
||||
*ppszOutFile = pszFile;
|
||||
printf(" %s -> %s\n", pszOrigFile, pszFile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK AddBywayCallback(_In_opt_ PVOID pContext,
|
||||
_In_opt_ LPCSTR pszFile,
|
||||
_Outptr_result_maybenull_ LPCSTR *ppszOutFile)
|
||||
{
|
||||
PBOOL pbAddedDll = (PBOOL)pContext;
|
||||
if (!pszFile && !*pbAddedDll) { // Add new byway.
|
||||
*pbAddedDll = TRUE;
|
||||
*ppszOutFile = s_szDllPath;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetFile(PCHAR pszPath)
|
||||
{
|
||||
BOOL bGood = TRUE;
|
||||
HANDLE hOld = INVALID_HANDLE_VALUE;
|
||||
HANDLE hNew = INVALID_HANDLE_VALUE;
|
||||
PDETOUR_BINARY pBinary = NULL;
|
||||
|
||||
CHAR szOrg[MAX_PATH];
|
||||
CHAR szNew[MAX_PATH];
|
||||
CHAR szOld[MAX_PATH];
|
||||
|
||||
szOld[0] = '\0';
|
||||
szNew[0] = '\0';
|
||||
|
||||
StringCchCopyA(szOrg, sizeof(szOrg), pszPath);
|
||||
StringCchCopyA(szNew, sizeof(szNew), szOrg);
|
||||
StringCchCatA(szNew, sizeof(szNew), "#");
|
||||
StringCchCopyA(szOld, sizeof(szOld), szOrg);
|
||||
StringCchCatA(szOld, sizeof(szOld), "~");
|
||||
printf(" %s:\n", pszPath);
|
||||
|
||||
hOld = CreateFileA(szOrg,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (hOld == INVALID_HANDLE_VALUE) {
|
||||
printf("Couldn't open input file: %s, error: %ld\n",
|
||||
szOrg, GetLastError());
|
||||
bGood = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
hNew = CreateFileA(szNew,
|
||||
GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (hNew == INVALID_HANDLE_VALUE) {
|
||||
printf("Couldn't open output file: %s, error: %ld\n",
|
||||
szNew, GetLastError());
|
||||
bGood = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
|
||||
printf("DetourBinaryOpen failed: %ld\n", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (hOld != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hOld);
|
||||
hOld = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
{
|
||||
BOOL bAddedDll = FALSE;
|
||||
|
||||
DetourBinaryResetImports(pBinary);
|
||||
|
||||
if (!s_fRemove) {
|
||||
if (!DetourBinaryEditImports(pBinary,
|
||||
&bAddedDll,
|
||||
AddBywayCallback, NULL, NULL, NULL)) {
|
||||
printf("DetourBinaryEditImports failed: %ld\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!DetourBinaryEditImports(pBinary, NULL,
|
||||
ListBywayCallback, ListFileCallback,
|
||||
NULL, NULL)) {
|
||||
|
||||
printf("DetourBinaryEditImports failed: %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
if (!DetourBinaryWrite(pBinary, hNew)) {
|
||||
printf("DetourBinaryWrite failed: %ld\n", GetLastError());
|
||||
bGood = FALSE;
|
||||
}
|
||||
|
||||
DetourBinaryClose(pBinary);
|
||||
pBinary = NULL;
|
||||
|
||||
if (hNew != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hNew);
|
||||
hNew = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (bGood) {
|
||||
if (!DeleteFileA(szOld)) {
|
||||
DWORD dwError = GetLastError();
|
||||
if (dwError != ERROR_FILE_NOT_FOUND) {
|
||||
printf("Warning: Couldn't delete %s: %ld\n", szOld, dwError);
|
||||
bGood = FALSE;
|
||||
}
|
||||
}
|
||||
if (!MoveFileA(szOrg, szOld)) {
|
||||
printf("Error: Couldn't back up %s to %s: %ld\n",
|
||||
szOrg, szOld, GetLastError());
|
||||
bGood = FALSE;
|
||||
}
|
||||
if (!MoveFileA(szNew, szOrg)) {
|
||||
printf("Error: Couldn't install %s as %s: %ld\n",
|
||||
szNew, szOrg, GetLastError());
|
||||
bGood = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
DeleteFileA(szNew);
|
||||
}
|
||||
|
||||
|
||||
end:
|
||||
if (pBinary) {
|
||||
DetourBinaryClose(pBinary);
|
||||
pBinary = NULL;
|
||||
}
|
||||
if (hNew != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hNew);
|
||||
hNew = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (hOld != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hOld);
|
||||
hOld = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return bGood;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void PrintUsage(void)
|
||||
{
|
||||
printf("Usage:\n"
|
||||
" setdll [options] binary_files\n"
|
||||
"Options:\n"
|
||||
" /d:file.dll : Add file.dll binary files\n"
|
||||
" /r : Remove extra DLLs from binary files\n"
|
||||
" /? : This help screen.\n");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////// main.
|
||||
//
|
||||
int CDECL main(int argc, char **argv)
|
||||
{
|
||||
BOOL fNeedHelp = FALSE;
|
||||
PCHAR pszFilePart = NULL;
|
||||
|
||||
int arg = 1;
|
||||
for (; arg < argc; arg++) {
|
||||
if (argv[arg][0] == '-' || argv[arg][0] == '/') {
|
||||
CHAR *argn = argv[arg] + 1;
|
||||
CHAR *argp = argn;
|
||||
while (*argp && *argp != ':' && *argp != '=')
|
||||
argp++;
|
||||
if (*argp == ':' || *argp == '=')
|
||||
*argp++ = '\0';
|
||||
|
||||
switch (argn[0]) {
|
||||
|
||||
case 'd': // Set DLL
|
||||
case 'D':
|
||||
if ((strchr(argp, ':') != NULL || strchr(argp, '\\') != NULL) &&
|
||||
GetFullPathNameA(argp, sizeof(s_szDllPath), s_szDllPath, &pszFilePart)) {
|
||||
}
|
||||
else {
|
||||
StringCchPrintfA(s_szDllPath, sizeof(s_szDllPath), "%s", argp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r': // Remove extra set DLLs.
|
||||
case 'R':
|
||||
s_fRemove = TRUE;
|
||||
break;
|
||||
|
||||
case '?': // Help
|
||||
fNeedHelp = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
fNeedHelp = TRUE;
|
||||
printf("Bad argument: %s:%s\n", argn, argp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argc == 1) {
|
||||
fNeedHelp = TRUE;
|
||||
}
|
||||
if (!s_fRemove && s_szDllPath[0] == 0) {
|
||||
fNeedHelp = TRUE;
|
||||
}
|
||||
if (fNeedHelp) {
|
||||
PrintUsage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (s_fRemove) {
|
||||
printf("Removing extra DLLs from binary files.\n");
|
||||
}
|
||||
else {
|
||||
if (!DoesDllExportOrdinal1(s_szDllPath)) {
|
||||
printf("Error: %hs does not export function with ordinal #1.\n",
|
||||
s_szDllPath);
|
||||
return 2;
|
||||
}
|
||||
printf("Adding %hs to binary files.\n", s_szDllPath);
|
||||
}
|
||||
|
||||
for (arg = 1; arg < argc; arg++) {
|
||||
if (argv[arg][0] != '-' && argv[arg][0] != '/') {
|
||||
SetFile(argv[arg]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// End of File
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
##############################################################################
|
||||
##
|
||||
## API Extention to Measure time slept.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\simple$(DETOURS_BITS).dll \
|
||||
$(BIND)\sleep5.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\simple$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\sleep5.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\simple.obj : simple.cpp
|
||||
|
||||
$(OBJD)\simple.res : simple.rc
|
||||
|
||||
$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\simple$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\simple.obj $(OBJD)\simple.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\simple.obj $(OBJD)\simple.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:TimedSleepEx \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\simple$(DETOURS_BITS).bsc : $(OBJD)\simple.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\simple.sbr
|
||||
|
||||
$(OBJD)\sleep5.obj : sleep5.cpp
|
||||
|
||||
$(BIND)\sleep5.exe : $(OBJD)\sleep5.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleep5.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\sleep5.bsc : $(OBJD)\sleep5.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleep5.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\simple*.* 2>nul
|
||||
-del $(BIND)\sleep5.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\simple$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\simple$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).dll : $(OPTD)\simple$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).pdb : $(OPTD)\simple$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\simple$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. ---------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should not load simple$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Adding simple$(DETOURS_BITS).dll to sleep5.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should load simple$(DETOURS_BITS).dll statically ----------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Removing simple$(DETOURS_BITS).dll from sleep5.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should not load simple$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should load simple$(DETOURS_BITS).dll dynamically using withdll.exe----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
|
||||
debug: all
|
||||
windbg -o $(BIND)\withdll.exe -d:$(BIND)\simple$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (simple.cpp of simple.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This DLL will detour the Windows SleepEx API so that TimedSleep function
|
||||
// gets called instead. TimedSleepEx records the before and after times, and
|
||||
// calls the real SleepEx API through the TrueSleepEx function pointer.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
|
||||
static LONG dwSlept = 0;
|
||||
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
|
||||
|
||||
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
DWORD dwBeg = GetTickCount();
|
||||
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
DWORD dwEnd = GetTickCount();
|
||||
|
||||
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured SleepEx().\n");
|
||||
}
|
||||
else {
|
||||
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring SleepEx(): %ld\n", error);
|
||||
}
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Removed SleepEx() (result=%ld), slept %ld ticks.\n", error, dwSlept);
|
||||
fflush(stdout);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for simple.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "simple" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "simple" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (sleep5.cpp of sleep5.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int __cdecl main(int argc, char ** argv)
|
||||
{
|
||||
if (argc == 2) {
|
||||
Sleep(atoi(argv[1]) * 1000);
|
||||
}
|
||||
else {
|
||||
printf("sleep5.exe: Starting.\n");
|
||||
|
||||
Sleep(5000);
|
||||
|
||||
printf("sleep5.exe: Done sleeping.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
##############################################################################
|
||||
##
|
||||
## API Extention to Measure time slept.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
CFLAGS=$(CFLAGS) /std:c++14
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\simple_safe$(DETOURS_BITS).dll \
|
||||
$(BIND)\sleep5.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\simple_safe$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\sleep5.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\simple_safe.obj : simple_safe.cpp
|
||||
|
||||
$(OBJD)\simple_safe.res : simple_safe.rc
|
||||
|
||||
$(BIND)\simple_safe$(DETOURS_BITS).dll $(BIND)\simple_safe$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\simple_safe.obj $(OBJD)\simple_safe.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\simple_safe.obj $(OBJD)\simple_safe.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:TimedSleepEx \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\simple_safe$(DETOURS_BITS).bsc : $(OBJD)\simple_safe.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\simple_safe.sbr
|
||||
|
||||
$(OBJD)\sleep5.obj : sleep5.cpp
|
||||
|
||||
$(BIND)\sleep5.exe : $(OBJD)\sleep5.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleep5.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console
|
||||
|
||||
$(OBJD)\sleep5.bsc : $(OBJD)\sleep5.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleep5.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\simple_safe*.* 2>nul
|
||||
-del $(BIND)\sleep5.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\simple_safe$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\simple_safe$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\simple_safe$(DETOURS_OPTION_BITS).dll : $(OPTD)\simple_safe$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\simple_safe$(DETOURS_OPTION_BITS).pdb : $(OPTD)\simple_safe$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\simple_safe$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\simple_safe$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. ---------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should not load simple_safe$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Adding simple_safe$(DETOURS_BITS).dll to sleep5.exe ------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\simple_safe$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should load simple_safe$(DETOURS_BITS).dll statically ----------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Removing simple_safe$(DETOURS_BITS).dll from sleep5.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should not load simple_safe$(DETOURS_BITS).dll -----------------------------------
|
||||
$(BIND)\sleep5.exe
|
||||
@echo.
|
||||
@echo -------- Should load simple_safe$(DETOURS_BITS).dll dynamically using withdll.exe----------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\simple_safe$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
@echo.
|
||||
|
||||
debug: all
|
||||
windbg -o $(BIND)\withdll.exe -d:$(BIND)\simple_safe$(DETOURS_BITS).dll $(BIND)\sleep5.exe
|
||||
|
||||
|
||||
################################################################# End of File.
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (simple_safe.cpp of simple_safe.dll)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This DLL will detour the Windows SleepEx API so that TimedSleep function
|
||||
// gets called instead. TimedSleepEx records the before and after times, and
|
||||
// calls the real SleepEx API through the TrueSleepEx function pointer.
|
||||
//
|
||||
// The difference between simple and simple_safe is that simple_safe
|
||||
// uses the C++ 14 overloads which help prevent mismatching types.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "detours.h"
|
||||
|
||||
static LONG dwSlept = 0;
|
||||
static DWORD (WINAPI * TrueSleepEx)(DWORD dwMilliseconds, BOOL bAlertable) = SleepEx;
|
||||
|
||||
DWORD WINAPI TimedSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
DWORD dwBeg = GetTickCount();
|
||||
DWORD ret = TrueSleepEx(dwMilliseconds, bAlertable);
|
||||
DWORD dwEnd = GetTickCount();
|
||||
|
||||
InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
LONG error;
|
||||
(void)hinst;
|
||||
(void)reserved;
|
||||
|
||||
if (DetourIsHelperProcess()) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dwReason == DLL_PROCESS_ATTACH) {
|
||||
DetourRestoreAfterWith();
|
||||
|
||||
printf("simple_safe" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Starting.\n");
|
||||
fflush(stdout);
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
if (error == NO_ERROR) {
|
||||
printf("simple_safe" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Detoured SleepEx().\n");
|
||||
}
|
||||
else {
|
||||
printf("simple_safe" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Error detouring SleepEx(): %ld\n", error);
|
||||
}
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourDetach(&TrueSleepEx, TimedSleepEx);
|
||||
error = DetourTransactionCommit();
|
||||
|
||||
printf("simple_safe" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:"
|
||||
" Removed SleepEx() (result=%ld), slept %ld ticks.\n", error, dwSlept);
|
||||
fflush(stdout);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version information for simple_safe.rc.
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include "detver.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "simple_safe" DETOURS_STRINGIFY(DETOURS_BITS)
|
||||
#define VER_ORIGINALFILENAME_STR "simple_safe" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
|
||||
#define VER_FILEDESCRIPTION_STR "Detours Test Module"
|
||||
#define VER_COMPANYNAME_STR "Microsoft Corporation"
|
||||
|
||||
#include "common.ver"
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (sleep5.cpp of sleep5.exe)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int __cdecl main(int argc, char ** argv)
|
||||
{
|
||||
if (argc == 2) {
|
||||
Sleep(atoi(argv[1]) * 1000);
|
||||
}
|
||||
else {
|
||||
printf("sleep5.exe: Starting.\n");
|
||||
|
||||
Sleep(5000);
|
||||
|
||||
printf("sleep5.exe: Done sleeping.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
##############################################################################
|
||||
##
|
||||
## API Extension to Measure time slept.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
CFLAGS = $(CFLAGS:/Od=/O2)
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\slept$(DETOURS_BITS).dll \
|
||||
$(BIND)\dslept$(DETOURS_BITS).dll \
|
||||
$(BIND)\sleepold.exe \
|
||||
$(BIND)\sleepnew.exe \
|
||||
$(BIND)\sleepbed.exe \
|
||||
\
|
||||
!IF $(DETOURS_SOURCE_BROWSING)==1
|
||||
$(OBJD)\slept$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\dslept$(DETOURS_BITS).bsc \
|
||||
$(OBJD)\sleepold.bsc \
|
||||
$(OBJD)\sleepnew.bsc \
|
||||
$(OBJD)\sleepbed.bsc \
|
||||
!ENDIF
|
||||
option
|
||||
|
||||
##############################################################################
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\slept.obj : slept.cpp verify.cpp
|
||||
|
||||
$(OBJD)\slept.res : slept.rc
|
||||
|
||||
$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\slept$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\slept.obj $(OBJD)\slept.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\slept.obj $(OBJD)\slept.res\
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:TimedSleepEx \
|
||||
/export:UntimedSleepEx \
|
||||
/export:GetSleptTicks \
|
||||
/export:TestTicks \
|
||||
/export:TestTicksEx \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\slept$(DETOURS_BITS).bsc : $(OBJD)\slept.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\slept.sbr
|
||||
|
||||
$(OBJD)\dslept.obj : dslept.cpp verify.cpp
|
||||
|
||||
$(OBJD)\dslept.res : dslept.rc
|
||||
|
||||
$(BIND)\dslept$(DETOURS_BITS).dll $(BIND)\dslept$(DETOURS_BITS).lib: \
|
||||
$(OBJD)\dslept.obj $(OBJD)\dslept.res $(DEPS)
|
||||
cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
|
||||
$(OBJD)\dslept.obj $(OBJD)\dslept.res \
|
||||
/link $(LINKFLAGS) /subsystem:console \
|
||||
/export:DetourFinishHelperProcess,@1,NONAME \
|
||||
/export:TimedSleepEx \
|
||||
/export:UntimedSleepEx \
|
||||
/export:GetSleptTicks \
|
||||
$(LIBS)
|
||||
|
||||
$(OBJD)\dslept$(DETOURS_BITS).bsc : $(OBJD)\dslept.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\dslept.sbr
|
||||
|
||||
$(OBJD)\sleepold.obj : sleepold.cpp verify.cpp
|
||||
|
||||
$(BIND)\sleepold.exe : $(OBJD)\sleepold.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepold.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no
|
||||
|
||||
$(OBJD)\sleepold.bsc : $(OBJD)\sleepold.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleepold.sbr
|
||||
|
||||
$(OBJD)\sleepnew.obj : sleepnew.cpp verify.cpp
|
||||
|
||||
$(BIND)\sleepnew.exe : $(OBJD)\sleepnew.obj $(BIND)\slept$(DETOURS_BITS).lib $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepnew.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no $(BIND)\slept$(DETOURS_BITS).lib
|
||||
|
||||
$(OBJD)\sleepnew.bsc : $(OBJD)\sleepnew.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleepnew.sbr
|
||||
|
||||
$(OBJD)\sleepbed.obj : sleepbed.cpp verify.cpp
|
||||
|
||||
$(BIND)\sleepbed.exe : $(OBJD)\sleepbed.obj $(DEPS)
|
||||
cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\sleepbed.obj \
|
||||
/link $(LINKFLAGS) $(LIBS) \
|
||||
/subsystem:console /fixed:no
|
||||
|
||||
$(OBJD)\sleepbed.bsc : $(OBJD)\sleepbed.obj
|
||||
bscmake /v /n /o $@ $(OBJD)\sleepbed.sbr
|
||||
|
||||
##############################################################################
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\slept*.* 2>nul
|
||||
-del $(BIND)\dslept*.* 2>nul
|
||||
-del $(BIND)\sleepold.* 2>nul
|
||||
-del $(BIND)\sleepnew.* 2>nul
|
||||
-del $(BIND)\sleepbed.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
############################################### Install non-bit-size binaries.
|
||||
|
||||
!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
|
||||
|
||||
$(OPTD)\slept$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\slept$(DETOURS_OPTION_BITS).pdb:
|
||||
$(OPTD)\dslept$(DETOURS_OPTION_BITS).dll:
|
||||
$(OPTD)\dslept$(DETOURS_OPTION_BITS).pdb:
|
||||
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).dll: $(OPTD)\slept$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).pdb: $(OPTD)\slept$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).dll: $(OPTD)\dslept$(DETOURS_OPTION_BITS).dll
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).pdb: $(OPTD)\dslept$(DETOURS_OPTION_BITS).pdb
|
||||
@if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
|
||||
|
||||
option: \
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\slept$(DETOURS_OPTION_BITS).pdb \
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).dll \
|
||||
$(BIND)\dslept$(DETOURS_OPTION_BITS).pdb \
|
||||
|
||||
!ELSE
|
||||
|
||||
option:
|
||||
|
||||
!ENDIF
|
||||
|
||||
##############################################################################
|
||||
|
||||
skype: all
|
||||
start windbg -G -o $(BIND)\withdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll "C:\Program Files (x86)\Skype\Phone\Skype.exe"
|
||||
|
||||
test: all
|
||||
@echo -------- Reseting test binaries to initial state. -----------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load detour self ----------------------------------------
|
||||
$(BIND)\sleepbed.exe
|
||||
@echo.
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
|
||||
$(BIND)\sleepnew.exe
|
||||
@echo.
|
||||
@echo -------- Should not load slept$(DETOURS_BITS).dll --------------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Adding slept$(DETOURS_BITS).dll to sleepold.exe -------------------------------
|
||||
$(BIND)\setdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll statically -------------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Replacing slept$(DETOURS_BITS).dll with dslept$(DETOURS_BITS).dll in sleepold.exe ------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
$(BIND)\setdll.exe -d:$(BIND)\dslept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load dslept$(DETOURS_BITS).dll instead of slept$(DETOURS_BITS).dll --------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Removing dslept$(DETOURS_BITS).dll from sleepold.exe --------------------------
|
||||
$(BIND)\setdll.exe -r $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should not load dslept$(DETOURS_BITS).dll or slept$(DETOURS_BITS).dll ------------------------
|
||||
$(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Should load slept$(DETOURS_BITS).dll dynamically using withdll.exe ------------
|
||||
$(BIND)\withdll.exe -d:$(BIND)\slept$(DETOURS_BITS).dll $(BIND)\sleepold.exe
|
||||
@echo.
|
||||
@echo -------- Test completed. ------------------------------------------------
|
||||
|
||||
################################################################# End of File.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue