gpt4 book ai didi

c - 加密 API 调用失败

转载 作者:太空宇宙 更新时间:2023-11-04 03:32:57 24 4
gpt4 key购买 nike

第一件事:

我的测试系统: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,它会独立于分配顺序工作。为什么它在 otherwise 中失败了?

最佳答案

您的代码有两个问题。首先是您正在使用 strlen 来确定缓冲区的大小解密的字符串。此函数不考虑空终止符“\0”(在您的代码中为 0x00案件)。这意味着缓冲区 pVAE_DpGTC_D 将比其对应的元素少一个包含加密字符串的缓冲区。第二个问题是您的 encrStr 函数。在里面,你在写超越使用语句 pOut[len] = 0x00; 的数组边界。用于访问数组的索引在 [0, len - 1] 范围内。 这就是你的函数的方式(假设你正在传递一个输出缓冲区,其中包含足够的元素用于字符串及其空终止符)应该被实现:

void encrStr(char *pStr, int len, char *pOut, char cryptochar)
{
// zero char must remain, therefore i < len
for (int i = 0; i < len - 1; i++)
{
pOut[i] = pStr[i] ^ cryptochar;
printf("%c\n", pOut[i]);
}
pOut[len - 1] = 0x00;
printf("%s\n", pOut);
}

当你越界写入时,你正在破坏你的数组周围的堆栈,你会遇到 UB(未定义的行为)。这就是此示例有时有效、有时无效的原因。一些编译器会就此警告您,但其他人不会。这些是 C++ 中的细微错误,可能会让您很头疼。查看这些链接有关未定义行为的更多信息:

What are all the common undefined behaviours that a C++ programmer should know about?

https://en.wikipedia.org/wiki/Undefined_behavior

关于c - 加密 API 调用失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34818303/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com