encryption的API调用失败

首先是:

我的testing系统:Windows 7 32位专业版Windows 7 64位专业版

编译器:gcc版本5.2.0(i686-win32-dwarf-rev0,由MinGW-W64项目build造)

构build选项:g ++ foo.cpp -o foo.exe

如何检测内存数据更改?

如何获得过去10年的夏令时间界限

相当于GetCommandLine和CommandLinetoArgv的Linux?

在Windows关机时,Windows服务如何运行?

如何以编程方式确定二进制输出中的构build系统等价性?

我的应用程序dynamic地从kernel32.dll接收函数地址。 这按预期工作。 但是,当我对这些API调用进行异或encryption并将解密的string传递给GetProcAdress函数时,取决于stringpVAE_D [strlen(pVAE_E)]的顺序。 和char pGTC_D [strlen(pGTC_E)]以及encryptionstring的顺序; 如果在char pVAE_D [strlen(pVAE_E)]之前设置字符pGTC_D [strlen(pGTC_E)](对于encryption的string是相同的)

`#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,0x0b,0x07,0x21,0x1c,0x00}; // VirtualAllocEx encrypted with d char pGTC_E[] = { 0x3d,0x1f,0x0e,0x2e,0x12,0x1b,0x1e,0x39,0x15,0x14,0x02,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,char cryptochar) { // zero char must remain,therefore i < len for (int i = 0; i < len; i++) { pOut[i] = pStr[i] ^ cryptochar; printf("%cn",pOut[i]); } pOut[len] = 0x00; printf("%sn",pOut); }`

如果我将解密缓冲区的内存大小增加1,它将独立于分配顺序。 为什么它在其他方面失败?

DPAPI – 为另一个用户encryption?

如何停止具有多个线程的Windows服务无法停止

WM_QUIT只发布线程而不是窗口?

升压asio计时器不阻止读取呼叫

在目录树中查找文件的最快方法是什么?

这是你的代码的两个问题。 首先,您正在使用strlen来确定解密字符串的缓冲区的大小。 这个函数不考虑空终止符字符' 0'(在你的情况下是0x00)。 这意味着缓冲区pVAE_D和pGTC_D一个元素比包含加密字符串的相应缓冲区少一个元素。 第二个问题是你的encrStr函数在这个例子中,你正在使用语句pOut[len] = 0x00;来写入超出数组的范围pOut[len] = 0x00; 。 访问数组的索引在[0,len – 1]的范围内。 这就是你的函数(假设你正在传递一个输出缓冲区,其中有足够的字符串元素和它的空终止符)应该被执行:

void encrStr(char *pStr,therefore i < len for (int i = 0; i < len - 1; i++) { pOut[i] = pStr[i] ^ cryptochar; printf("%cn",pOut[i]); } pOut[len - 1] = 0x00; printf("%sn",pOut); }

当你写入超出数组范围的时候,你正在破坏你的数组的堆栈,并且遇到UB(未定义的行为)。 这就是为什么这个样本有时会起作用,而有些时候却不行。 有些编译器会提醒你这个,但其他编译器则不会。 这些在C ++中是微妙的错误,可能会导致你很多头痛。 查看这些链接,了解更多关于未定义行为的信息:

C ++程序员应该知道的所有常见的未定义行为是什么?

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

相关文章

本篇内容主要讲解“gitee如何上传代码”,感兴趣的朋友不妨来...
这篇“从gitee上下的代码如何用”文章的知识点大部分人都不太...
这篇文章主要介绍“gitee如何下载仓库里的项目”,在日常操作...
本篇内容主要讲解“怎么在Gitee上更新代码”,感兴趣的朋友不...
本文小编为大家详细介绍“怎么将工程托管到gitee”,内容详细...
这篇文章主要介绍了gitee中图片大小如何调整的相关知识,内容...