文章目录
- openssl3.2 - exp - 使用默认的函数宏,在release版中也会引入__FILE__
- 概述
- 笔记
- 验证是否__FILE__在release版下也能用?
- 将openssl编译成release版的,看看CRYPTO_free()是否只需要一个参数就行?
- 将工程中的openssl相关的库换成release版的,再试试是否还会引入__FILE__
- 折中方法
- END
openssl3.2 - exp - 使用默认的函数宏,在release版中也会引入__FILE__
概述
在加固主程序。
主程序已经确定是release版的了。
用IDA打开,还是能看到很多相关的__FILE__的痕迹。
查这些串的引用点。
原来是openssl释放内存的函数要的参数。
因为我写程序时为了方便,就编译了一个debug版的openssl3.2.
查看openssl3.2的API定义。
#define MY_OPENSSL_FREE(p) \
do { \
if (NULL != p) \
{ \
OPENSSL_free(p); \
p = NULL; \
} \
} while (false);
# define OPENSSL_free(addr) \
CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE)
void CRYPTO_free(void *ptr, const char *file, int line);
可以看到最后调用的CRYPTO_free()是debug版的,就是需要file,line.
也就是这个原因,让编译器将__FILE__, __LINE__送给了CRYPTO_free()作为参数。从而在PE字符串表中留下了不必要的字符串。
笔记
验证是否__FILE__在release版下也能用?
#define __TEXTA(quote) quote
#define TEXTA(quote) __TEXTA(quote)
CStringA vs_build_type_detected(bool switchOn)
{
CStringA cs_rc;
if (switchOn)
{
#if (!defined(_DEBUG) && defined(NDEBUG))
cs_rc = TEXTA("Release build");
#elif (defined(_DEBUG) && !defined(NDEBUG))
cs_rc = TEXTA("debug build");
#else
#error 未知配置
#endif
}
return cs_rc;
}
void CvsBuildModeDiffDlg::OnBnClickedOk()
{
USES_CONVERSION;
CStringA csTmpA;
CStringW csTmpW;
csTmpA = vs_build_type_detected(true);
csTmpA.Format(TEXTA("%s - %s:%d"), csTmpA, __FILE__, __LINE__);
csTmpW = A2W(csTmpA.GetString());
AfxMessageBox(csTmpW);
CDialogEx::OnOK();
}
可以看到,release版下,可以正常使用__FILE__, LINE, 这2个宏和debug/release版没关系。
将openssl编译成release版的,看看CRYPTO_free()是否只需要一个参数就行?
已经做了实验,编译了一个release版的openssl3.2 (openssl3.2 - 编译)
将工程中的openssl相关的库换成release版的,再试试是否还会引入__FILE__
void CvsBuildModeDiffDlg::test()
{
USES_CONVERSION;
std::string str;
CString csW;
char* pBuf = NULL;
//# define OPENSSL_VERSION 0
//# define OPENSSL_CFLAGS 1
//# define OPENSSL_BUILT_ON 2
//# define OPENSSL_PLATFORM 3
//# define OPENSSL_DIR 4
//# define OPENSSL_ENGINES_DIR 5
//# define OPENSSL_VERSION_STRING 6
//# define OPENSSL_FULL_VERSION_STRING 7
//# define OPENSSL_MODULES_DIR 8
//# define OPENSSL_CPU_INFO 9
str += OpenSSL_version(OPENSSL_VERSION); // OpenSSL 3.2.0 23 Nov 2023
str += "\r\n";
str += OpenSSL_version(OPENSSL_CFLAGS); // compiler: cl /Zi /Fdossl_static.pdb /Gs0 /GF /Gy /MDd /W3 /wd4090 /nologo /Od -DLIBZ=".\\\\my_zlib_1d3.dll" -DL_ENDIAN -DOPENSSL_PIC -D"OPENSSL_BUILDING_OPENSSL" -D"ZLIB" -D"ZLIB_SHARED" -D"OPENSSL_SYS_WIN32" -D"WIN32_LEAN_AND_MEAN" -D"UNICODE" -D"_UNICODE" -D"_CRT_SECURE_NO_DEPRECATE" -D"_WINSOCK_DEPRECATED_NO_WARNINGS" -D"DEBUG" -D"_DEBUG" -I"D:\\my_dev\\lib\\zlib_1d3"
str += "\r\n";
str += OpenSSL_version(OPENSSL_BUILT_ON); // built on: Sun Feb 25 02:20:27 2024 UTC
str += "\r\n";
str += OpenSSL_version(OPENSSL_PLATFORM); // platform: VC-WIN64A
str += "\r\n";
str += OpenSSL_version(OPENSSL_DIR); // OPENSSLDIR: "C:\openssl_3d2\common"
str += "\r\n";
str += OpenSSL_version(OPENSSL_ENGINES_DIR); // ENGINESDIR: "C:\openssl_3d2\lib\engines-3"
str += "\r\n";
str += OpenSSL_version(OPENSSL_VERSION_STRING); // 3.2.0
str += "\r\n";
str += OpenSSL_version(OPENSSL_FULL_VERSION_STRING); // 3.2.0
str += "\r\n";
str += OpenSSL_version(OPENSSL_MODULES_DIR); // MODULESDIR: "C:\openssl_3d2\lib\ossl-modules"
str += "\r\n";
str += OpenSSL_version(OPENSSL_CPU_INFO); // CPUINFO: OPENSSL_ia32cap=0x7ffaf3ffffebffff:0x18c07fcef3bfa7eb
str += "\r\n";
pBuf = (char*)OPENSSL_malloc(10); // !
assert(NULL != pBuf);
OPENSSL_free(pBuf); // !
pBuf = NULL;
str;
csW = A2W(str.data());
AfxMessageBox(csW);
}
void CvsBuildModeDiffDlg::OnBnClickedOk()
{
USES_CONVERSION;
CStringA csTmpA;
CStringW csTmpW;
test();
csTmpA = vs_build_type_detected(true);
csTmpA.Format(TEXTA("%s - %s:%d"), csTmpA, __FILE__, __LINE__);
csTmpW = A2W(csTmpA.GetString());
AfxMessageBox(csTmpW);
CDialogEx::OnOK();
}
看了一下,还是会引入__FILE_
原因是CRYPTO_malloc(), CRYPTO_free()都是3个参数的,后2个参数就是文件名和行号
OSSL_CRYPTO_ALLOC void *CRYPTO_malloc(size_t num, const char *file, int line);
void CRYPTO_free(void *ptr, const char *file, int line);
openssl的函数这么封装,是为了有内存泄漏时,容易知道原始泄漏点的代码所在.cpp和行号。
不过,对于release版,为啥不提供只有一个参数的版本呢?
折中方法
如果在IDA中发现使用opensslAPI引入了__FILE_, 那么就仿照openssl的函数宏,自己封装函数宏,就不会引入__FILE__了。
#if (!defined(_DEBUG) && defined(NDEBUG))
// Release build
// release版中使用的是自己给参数的函数宏,给的file = "", line = 0
# define my_OPENSSL_malloc(num) \
CRYPTO_malloc(num, "", 0)
# define my_OPENSSL_free(addr) \
CRYPTO_free(addr, "", 0)
#elif (defined(_DEBUG) && !defined(NDEBUG))
// debug build
// debug版中使用openssl原始的函数宏,可以引入__FILE__
# define my_OPENSSL_malloc(num) OPENSSL_malloc(num)
# define my_OPENSSL_free(addr) OPENSSL_free(addr)
#else
#error 未知配置
#endif
void CvsBuildModeDiffDlg::test()
{
USES_CONVERSION;
std::string str;
CString csW;
char* pBuf = NULL;
//# define OPENSSL_VERSION 0
//# define OPENSSL_CFLAGS 1
//# define OPENSSL_BUILT_ON 2
//# define OPENSSL_PLATFORM 3
//# define OPENSSL_DIR 4
//# define OPENSSL_ENGINES_DIR 5
//# define OPENSSL_VERSION_STRING 6
//# define OPENSSL_FULL_VERSION_STRING 7
//# define OPENSSL_MODULES_DIR 8
//# define OPENSSL_CPU_INFO 9
str += OpenSSL_version(OPENSSL_VERSION); // OpenSSL 3.2.0 23 Nov 2023
str += "\r\n";
str += OpenSSL_version(OPENSSL_CFLAGS); // compiler: cl /Zi /Fdossl_static.pdb /Gs0 /GF /Gy /MDd /W3 /wd4090 /nologo /Od -DLIBZ=".\\\\my_zlib_1d3.dll" -DL_ENDIAN -DOPENSSL_PIC -D"OPENSSL_BUILDING_OPENSSL" -D"ZLIB" -D"ZLIB_SHARED" -D"OPENSSL_SYS_WIN32" -D"WIN32_LEAN_AND_MEAN" -D"UNICODE" -D"_UNICODE" -D"_CRT_SECURE_NO_DEPRECATE" -D"_WINSOCK_DEPRECATED_NO_WARNINGS" -D"DEBUG" -D"_DEBUG" -I"D:\\my_dev\\lib\\zlib_1d3"
str += "\r\n";
str += OpenSSL_version(OPENSSL_BUILT_ON); // built on: Sun Feb 25 02:20:27 2024 UTC
str += "\r\n";
str += OpenSSL_version(OPENSSL_PLATFORM); // platform: VC-WIN64A
str += "\r\n";
str += OpenSSL_version(OPENSSL_DIR); // OPENSSLDIR: "C:\openssl_3d2\common"
str += "\r\n";
str += OpenSSL_version(OPENSSL_ENGINES_DIR); // ENGINESDIR: "C:\openssl_3d2\lib\engines-3"
str += "\r\n";
str += OpenSSL_version(OPENSSL_VERSION_STRING); // 3.2.0
str += "\r\n";
str += OpenSSL_version(OPENSSL_FULL_VERSION_STRING); // 3.2.0
str += "\r\n";
str += OpenSSL_version(OPENSSL_MODULES_DIR); // MODULESDIR: "C:\openssl_3d2\lib\ossl-modules"
str += "\r\n";
str += OpenSSL_version(OPENSSL_CPU_INFO); // CPUINFO: OPENSSL_ia32cap=0x7ffaf3ffffebffff:0x18c07fcef3bfa7eb
str += "\r\n";
pBuf = (char*)my_OPENSSL_malloc(10);
assert(NULL != pBuf);
my_OPENSSL_free(pBuf);
pBuf = NULL;
str;
csW = A2W(str.data());
AfxMessageBox(csW);
}
void CvsBuildModeDiffDlg::OnBnClickedOk()
{
USES_CONVERSION;
CStringA csTmpA;
CStringW csTmpW;
test();
csTmpA = vs_build_type_detected(true);
csTmpA.Format(TEXTA("%s - %s:%d"), csTmpA, __FILE__, __LINE__);
csTmpW = A2W(csTmpA.GetString());
AfxMessageBox(csTmpW);
CDialogEx::OnOK();
}
可以看到,使用自己定义的函数宏后,在IDA中看时,已经没有引入__FILE_了。