[C++] 纯文本查看 复制代码
// rFile.cpp : 定义控制台应用程序的入口点。
//
#include <windows.h>
#include <stdio.h>
#include <string>
#include <vector>
DWORD Search_Bin(byte *pSrc, byte *pTrait, size_t nSrcLen, size_t nTraitLen)//内存搜索
{
if (IsBadReadPtr(pSrc, sizeof(void*)) == TRUE)
{
return -1;
}
ULONG i, j, k;
for (i = 0; i <= (nSrcLen - nTraitLen); i++)
{
if (pSrc[i] == pTrait[0])
{
k = i;
j = 0;
while (j < nTraitLen)
{
k++; j++;
if (pSrc[k] != pTrait[j])
{
break;
}
}
if (j == nTraitLen)
{
return i;
}
}
}
return -1;
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
puts("******************************************************");
puts("支持 x86/x64文件,exe|dll|sys|ocx");
puts("/l 随机连接器版本 ");
puts("/t 随机时间戳 ");
puts("/s 随机区段名 ");
puts("/oep 随机入口点 不支持大于4G文件");
puts("/ssize 随机区段大小 只随机 VSize和最后一个区段的RSize");
puts(" Ver 0.1");
puts("******************************************************");
return 0;
}
srand(GetTickCount());
HANDLE hFile;
DWORD dwFileSize = 0,dwHighSize = 0,dwReadSize = 0;
byte *pFile = NULL;
BOOL bRead = FALSE;
hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("打开文件失败 错误代码 = %d", GetLastError());
return 0;
}
dwFileSize = GetFileSize(hFile, &dwHighSize);
pFile = (byte*)calloc(dwFileSize * 2, sizeof(byte));
bRead = ReadFile(hFile, pFile, dwFileSize, &dwReadSize, NULL);
if (!bRead)
{
printf("读取文件失败 错误代码 = %d", GetLastError());
return 0;
}
CloseHandle(hFile);
PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)pFile;
if (pDosHead->e_magic != IMAGE_DOS_SIGNATURE)
{
puts("非标准PE文件");
return 0;
}
PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((LONG)pDosHead + pDosHead->e_lfanew);
PIMAGE_NT_HEADERS64 pNtHead64 = (PIMAGE_NT_HEADERS64)((LONG)pDosHead + pDosHead->e_lfanew);
if (pNtHead->Signature != IMAGE_NT_SIGNATURE)
{
puts("非标准PE文件");
return 0;
}
BOOL bX86 = FALSE;
if (pNtHead->FileHeader.Characteristics & IMAGE_FILE_32BIT_MACHINE)
bX86 = TRUE;
printf("文件系统: %s\n", bX86 ? "32Bits" : "64Bits");
for (int i = 0; i < argc; i++)
{
if (strcmp(argv[i], "/l") == 0)//随机连接器版本
{
pNtHead->OptionalHeader.MajorLinkerVersion = rand() % 88;//连接器版本随机
pNtHead->OptionalHeader.MinorLinkerVersion = rand() % 88;
puts("随机链接器版本 成功...");
}
if (strcmp(argv[i], "/t") == 0)//随机时间戳
{
pNtHead->FileHeader.TimeDateStamp = *(DWORD*)((DWORD)pFile + rand() % dwFileSize);//时间戳随机
puts("随机时间戳 成功...");
}
if (strcmp(argv[i], "/s") == 0)//随机区段名
{
int nSection = pNtHead->FileHeader.NumberOfSections;
DWORD tmp = (DWORD)pNtHead + sizeof(IMAGE_FILE_HEADER) + pNtHead->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_NT_SIGNATURE);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)tmp;
for (int i = 0; i < nSection; i++)
{
for (int j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++)
{
pSection->Name[j] = (rand() % ('z' - 'a')) + 'a';
}
pSection++;
}
puts("随机区段名 成功...");
}
if (strcmp(argv[i], "/oep") == 0)//随机入口点
{
DWORD dwEntryPoint = 0;
if (bX86)
dwEntryPoint = pNtHead->OptionalHeader.AddressOfEntryPoint;
else
dwEntryPoint = pNtHead64->OptionalHeader.AddressOfEntryPoint;
int nSection = pNtHead->FileHeader.NumberOfSections;
DWORD tmp = (DWORD)pNtHead + sizeof(IMAGE_FILE_HEADER) + pNtHead->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_NT_SIGNATURE);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)tmp;
for (int i = 0; i < nSection; i++)
{
if (dwEntryPoint >= pSection->VirtualAddress && dwEntryPoint <= (pSection->VirtualAddress + pSection->Misc.VirtualSize))//找到了代码区段
{
break;
}
pSection++;
}
byte byCode[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC };
byte* pSearch = pFile + pSection->PointerToRawData;
DWORD dwSearch = pSection->SizeOfRawData;
DWORD dwTemp = 0;
std::vector<DWORD> dwResult;
while (TRUE)
{
dwTemp = Search_Bin(pSearch, byCode, dwSearch, sizeof(byCode));
if (dwTemp != -1)
dwResult.push_back(dwTemp +(DWORD)pSearch);
else
break;
pSearch += dwTemp; pSearch += sizeof(byCode);
dwSearch -= dwTemp; dwSearch -= sizeof(byCode);
}
if (dwResult.size() == 0)
{
puts("随机入口点失败,找不到间隔代码...");
goto _FAIL_RAND_OEP;
}
DWORD dwRAddr = dwResult[rand() % dwResult.size()];
DWORD dwRAddrOffset = dwRAddr - pSection->PointerToRawData - (DWORD)pFile;
DWORD dwVAddr = pSection->VirtualAddress + dwRAddrOffset;//文件偏移地址转换为虚拟地址
byte jmp[] = { 0xE9, 0, 0, 0, 0 };
dwTemp = dwEntryPoint - dwVAddr - 5;
memcpy(&jmp[1], &dwTemp, sizeof(void*));
memcpy((void*)dwRAddr, jmp, sizeof(jmp));
if (bX86)
pNtHead->OptionalHeader.AddressOfEntryPoint = dwVAddr;
else
pNtHead64->OptionalHeader.AddressOfEntryPoint = dwVAddr;
puts("随机入口点 成功...");
_FAIL_RAND_OEP:
;
}
if (strcmp(argv[i], "/ssize") == 0)//随机区段大小
{
int nSection = pNtHead->FileHeader.NumberOfSections;
DWORD tmp = (DWORD)pNtHead + sizeof(IMAGE_FILE_HEADER) + pNtHead->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_NT_SIGNATURE);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)tmp;
DWORD dwAlig = 0;
DWORD dwRandAddSize = 0;
if (bX86)
dwAlig = pNtHead->OptionalHeader.SectionAlignment; //区段对齐
else
dwAlig = pNtHead64->OptionalHeader.SectionAlignment;
for (int i = 0; i < nSection; i++)//随机VSize
{
dwRandAddSize = rand() % (dwAlig - (pSection->Misc.VirtualSize % dwAlig));
pSection->Misc.VirtualSize += dwRandAddSize;
pSection++;
}
puts("随机VSize 成功...");
DWORD dwFileAlig;
DWORD dwRandAddFileSize = 0;
DWORD dwSizeofImage = 0;
if (bX86)
dwFileAlig = pNtHead->OptionalHeader.FileAlignment; //文件对齐
else
dwFileAlig = pNtHead64->OptionalHeader.FileAlignment;
dwRandAddFileSize = rand() % 18 + 1;
dwRandAddFileSize *= dwFileAlig;
pSection = (PIMAGE_SECTION_HEADER)tmp;
for (int i = 0; i < nSection -1 ; i++)//跳转到最后一个区段
pSection++;
if (pSection->SizeOfRawData + pSection->PointerToRawData != dwFileSize)
{
puts("文件存在附加数据,改变RSize失败...");
goto _FAIL_RAND_RSIZE;
}
pSection->Misc.VirtualSize += dwRandAddFileSize;
pSection->SizeOfRawData += dwRandAddFileSize;
dwSizeofImage = pSection->VirtualAddress + pSection->Misc.VirtualSize;
for (int i = 0; i < (dwSizeofImage / dwAlig * 2); i++)
{
if (i * dwAlig >= dwSizeofImage)
{
if (bX86)
pNtHead->OptionalHeader.SizeOfImage = i*dwAlig;
else
pNtHead64->OptionalHeader.SizeOfImage = i*dwAlig;
dwFileSize += dwRandAddFileSize;
puts("随机RSize 成功...");
break;
}
}
_FAIL_RAND_RSIZE:
;
}
}
FILE *fp;
std::string strPrev(argv[1]),strName, strFileEx,strFileName;
int nPos = 0, nnPos = 0;
nPos = strPrev.rfind(".");
strName = strPrev.substr(0, nPos);
strFileEx = strPrev.substr(nPos, strPrev.length() - nPos);
strFileName = strName; strFileName += ".r"; strFileName += strFileEx;
fp = fopen(strFileName.c_str(), "wb+");
fwrite(pFile, dwFileSize, 1, fp);
fclose(fp);
return 0;
}