- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在阅读了几本关于密码学和运行时 PE 加密程序的白皮书后,我决定自己编写。它非常简单,仅用于教育目的。
这是 GitHub 存储库:https://github.com/Jyang772/XOR_Crypter
我有两个问题。
Shared
文件。我必须右键单击它并选择与 Nobody
共享。这与文件访问和安全权限有关吗?我正在使用 CreateFile()
和 Readfile
来读取和写入输入和输出文件。 http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
这是我的异或实现:
fs = 字节大小Rsize = 字节大小应该是一样的。
build 者:
char cipher[] ="penguin";
for (int i = 0; i < fs; i++)
{
FB[i] ^= cipher[i % strlen(cipher)]; // Simple Xor chiper
}
stub :
char cipher[] = "penguin";
for (int i = 0; i < Rsize; i++)
{
RData[i] ^= cipher[i % strlen(cipher)];
}
如果我在Builder和Stub中注释掉加密函数,加密文件运行良好。呃,除了权限错误。
我还试图包含一个选项菜单,用户可以在其中选择所使用的加密方法。也许我在那里做错了什么? Builder.exe 将包含用户选择的一个字节添加到 FB
缓冲区的末尾。 Stub.exe 读取并确定使用哪种加密方法来解密数据。
最佳答案
首先,使用异或“加密”,您的“加密”和“解密”功能应该相同:
void xor_crypt(const char *key, int key_len, char *data, int data_len)
{
for (int i = 0; i < data_len; i++)
data[i] ^= key[ i % key_len ];
}
您应该能够在“XOR Crypter”程序和“Stub”程序中使用相同的函数。
这不是很 C++ 风格;通常你会使用 std::string
或 std::vector
.例如:
void xor_crypt(const std::string &key, std::vector<char>& data)
{
for (size_t i = 0; i != data.size(); i++)
data[i] ^= key[ i % key.size() ];
}
然后在调用它的程序中声明:
std::string key = "penguin";
你会像这样阅读你的文件:
std::vector<char> file_data; // With your current program, make this a global.
fs = GetFileSize(efile, NULL);
file_data.resize(fs); // set vector length equal to file size
// Note: Replace &( file_data[0] ) with file_data.data() if you have C++11 support
ReadFile(efile, (LPVOID)( &( file_data[0] )), fs, &bt, NULL);
if (fs != bt)
// error reading file: report it here.
然后您只需使用 xor_crypt( key, file_data );
进行加密.要将 XOR 加密数据写入您的资源,我相信您会调用现有函数:
// replace &( file_data[0] ) with file_data.data() if C++11
WriteToResources(output, 1, (BYTE *)&( file_data[0] ), file_data.size() );
我怀疑真正的问题出在您使用的 Windows API 上。是否LoadResource
给你可变数据,还是你需要复制它?我不知道 Windows API,但如果 LoadResource
我不会感到惊讶给你一个只读的拷贝。
如果您确实需要制作自己的拷贝以修改资源,那么在您的“ stub ”程序中恢复异或加密资源应该如下所示:
std::vector<char> RData;
void Resource(int id)
{
size_t Rsize;
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(1), RT_RCDATA);
HGLOBAL temp = LoadResource(NULL, hResource);
Rsize = SizeofResource(NULL, hResource);
RData.resize(RSize);
memcpy( (void*)&(RData[0]), temp, RSize ); // replace &RData[0] with RData.data() if C++11
}
你的“ stub ”中的解密应该是xor_crypt( key, RData );
.
我还有最后一个想法。我在您的“ stub ”程序中看到的最大错误是这一行:
switch (RData[strlen(RData)-1])
一旦您对数据进行异或加密,一些字节将变为零。 strlen()
函数不会返回 RData
中最后一个字节的索引。因此。而且,还有一个不同的、更微妙的错误:这将返回字符串的最后一个字节,而不是资源的最后一个字节。我真的看不出这条线是如何正确的;相反,我怀疑当加密被禁用时你的程序正在运行,通过下降到 default
开关盒。
如果您真的打算根据资源负载的最后一个字节来区分不同类型的数据,那么您真的应该只使用 Windows API 返回的大小来查找该字节。
如果您切换到使用 vector<char>
正如我上面所建议的,那么你可以用 RData.back()
找到它.否则,如果您继续使用 char *
, 那么那个字节就是 RData[RSize - 1]
.
关于C++异或加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20365005/
我是一名优秀的程序员,十分优秀!