【发布时间】:2016-01-15 19:23:06
【问题描述】:
第一件事:
我的测试系统:Windows 7 32 位专业版 Windows 7 64 位专业版
编译器: gcc 5.2.0版(i686-win32-dwarf-rev0,由MinGW-W64项目构建)
编译选项:g++ foo.cpp -o foo.exe
我的应用程序从 kernel32.dll 动态接收函数地址。 这按预期工作。但是,当我对这些 API 调用进行异或加密并将解密的字符串传递给 GetProcAdress 函数时,它会失败,具体取决于 char pVAE_D[strlen(pVAE_E)]; 的顺序。和 char pGTC_D[strlen(pGTC_E)] 以及加密字符串的顺序;如果我在 char pVAE_D[strlen(pVAE_E)] 之前设置 char pGTC_D[strlen(pGTC_E)] (加密字符串相同)
`#include <windows.h>
#include <stdio.h>
typedef BOOL(WINAPI* _GetThreadContext)
(HANDLE hThread,
LPCONTEXT lpContext
);
typedef LPVOID(WINAPI* _VirtualAllocEx)
(HANDLE handle_Process,
LPVOID longpointer_Address,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
void encrStr(char *pStr, int len, char *pOut, char cryptochar);
int main(void)
{
char pVAE_E[] = {0x32, 0x0d, 0x16, 0x10, 0x11, 0x05, 0x08, 0x25, 0x08, 0x08,
0x0b, 0x07, 0x21, 0x1c, 0x00}; // VirtualAllocEx encrypted with d
char pGTC_E[] = {
0x3d, 0x1f, 0x0e, 0x2e, 0x12, 0x08, 0x1f, 0x1b, 0x1e, 0x39, 0x15, 0x14,
0x0e, 0x1f, 0x02, 0x0e, 0x00}; // GetThreadContext encrypted with z
char pVAE_D[strlen(pVAE_E)];
char pGTC_D[strlen(pGTC_E)];
encrStr(pVAE_E, strlen(pVAE_E), pVAE_D, 'd');
encrStr(pGTC_E, strlen(pGTC_E), pGTC_D, 'z');
HMODULE hKernel32 = LoadLibraryA("kernel32.dll");
FARPROC fpGetThreadContext = GetProcAddress(hKernel32, pGTC_D);
if (fpGetThreadContext == NULL)
{
printf("gtc failed.\n");
}
_GetThreadContext kernel32GetThreadContext =
(_GetThreadContext)fpGetThreadContext;
FARPROC fpVirtualAllocEx = GetProcAddress(hKernel32, pVAE_D);
if (fpVirtualAllocEx == NULL)
{
printf("vae failed.\n");
}
_VirtualAllocEx kernel32VirtualAllocEx = (_VirtualAllocEx)fpVirtualAllocEx;
}
void encrStr(char *pStr, int len, char *pOut, char cryptochar)
{
// zero char must remain, therefore i < len
for (int i = 0; i < len; i++)
{
pOut[i] = pStr[i] ^ cryptochar;
printf("%c\n", pOut[i]);
}
pOut[len] = 0x00;
printf("%s\n", pOut);
}`
如果我将解密缓冲区的内存大小增加 1,它的工作原理与分配顺序无关。为什么它会在 else 中失败?
【问题讨论】:
-
请从您的问题中去除不相关的信息和代码,并专注于您遇到的问题。请提供MCVE(强调minimal)。对
LoadLibraryA、GetProcAddress的调用以及相关的函数指针调用与问题完全无关。 -
通常
pOut[len]是无效索引。最后一个元素应该是pOut[len - 1]
标签: c windows winapi encryption