原帖見fly寫的http://bbs.pediy.com/showthread.php?t=21910
寫了個程序 自動修復了下。。。。本來想用純C寫的 沒想到fread 在讀取
連在一起的兩個ODH時 只讀了一個 直接導致 逆出來的 校驗和函數 校驗和
計算不正確 所以換SDK了 可能是我fopen時模式沒有選上b 導致的 能檢查
出這個錯誤 真是運氣 雖然浪費了3小時。。。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#define __in
#define __out
#define __in__out
#define DEBUG__XU
#define MAX_LENGTH 0x10000
#define SUN_LENGTH 0xc
void get_checksun(__in unsigned char *ReadBuffer, __in unsigned int ReadLength, __in__out unsigned int *pCheckSun);
int get_filename(__in char **argv, __in__out char *FileName);
int get_filesize(__in HANDLE hFile, __out unsigned int *pSunLength);
int is_pe(__in PIMAGE_DOS_HEADER peHeader);
int get_overlay(__in PIMAGE_DOS_HEADER peHeader, __out unsigned int *pOverlay);
int main(int argc, char **argv)
{
char *ReadBuffer;
char FileName[MAX_PATH];
unsigned int ReadLength;
unsigned int SumLength;
unsigned int CheckSun;
unsigned int i;
unsigned int OverlayStart;
HANDLE hFile;
unsigned int retlength;
BOOL xx;
if(0 == get_filename(argv, FileName))
{
printf("no file/n");
}
hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
printf("open file error %d /n", GetLastError());
return 0;
}
get_filesize(hFile, &SumLength);
//得到有效數據大小
SumLength -= SUN_LENGTH;
//計算校驗值
xx = TRUE;
CheckSun = 1;
ReadBuffer = (char *)malloc(MAX_LENGTH);
i = 0;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
do
{
ReadLength = (i+MAX_LENGTH) <= SumLength ?MAX_LENGTH : (SumLength - i);
i += ReadLength;
ReadFile(hFile, ReadBuffer, ReadLength, &retlength, NULL);
//計算附加數據起始地址
if(xx)
{
if(!get_overlay((PIMAGE_DOS_HEADER)ReadBuffer, &OverlayStart))
{
return 0;
}
xx = FALSE;
}
get_checksun(ReadBuffer, ReadLength, &CheckSun);
}while(i < SumLength);
free(ReadBuffer);
//修正校驗值
SumLength ^= 0xAAAAAAAA;
CheckSun ^= 0xAAAAAAAA;
OverlayStart ^= 0xAAAAAAAA;
#ifdef DEBUG__XU
printf("%X %X %X/n", SumLength, OverlayStart, CheckSun);
getchar();
#endif
SetFilePointer(hFile, -SUN_LENGTH,NULL, SEEK_END);
WriteFile(hFile, &SumLength, sizeof(int), &retlength, NULL);
WriteFile(hFile, &OverlayStart, sizeof(int), &retlength, NULL);
WriteFile(hFile, &CheckSun, sizeof(int), &retlength, NULL);
CloseHandle(hFile);
return 1;
}
int is_pe(__in PIMAGE_DOS_HEADER peHeader)
{
char *Buffer;
Buffer = (char *)peHeader;
if('M' == *Buffer && 'Z' == *(Buffer + 1))
{
Buffer += *(unsigned int *)(Buffer +0x3c);
if('P' == *Buffer && 'E' == *(Buffer + 1))
{
return 1;
}
}
return 0;
}
int get_overlay(__in PIMAGE_DOS_HEADER peHeader, __out unsigned int *pOverlay)
{
PIMAGE_SECTION_HEADER peSec;
PIMAGE_NT_HEADERS32 pNtHeader;
if(!is_pe(peHeader))
{
printf("file is not PE /n");
return 0;
}
pNtHeader = (PIMAGE_NT_HEADERS32)(peHeader->e_lfanew + (DWORD)peHeader);
peSec = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader->FileHeader.SizeOfOptionalHeader + (DWORD)&pNtHeader->OptionalHeader);
while(peSec->VirtualAddress)
{
peSec++;
}
peSec--;
*pOverlay = peSec->PointerToRawData + peSec->SizeOfRawData;
#ifdef DEBUG__XU
printf("overlay start: %X/n", *pOverlay);
getchar();
#endif
return 1;
}
int get_filesize(__in HANDLE hFile, __out unsigned int *pSunLength)
{
*pSunLength = GetFileSize(hFile, NULL);
#ifdef DEBUG__XU
printf("file size: %X/n", *pSunLength);
getchar();
#endif
return 1;
}
int get_filename(__in char **argv, __in__out char *FileName)
{
if(NULL == *++argv)
{
printf("enter unpacked autoit file: /n");
if(0 == scanf("%s", FileName))
{
return 0;
}
fflush(stdin);
}
else
{
strcpy(FileName, *argv);
}
return 1;
}
void get_checksun(__in unsigned char *ReadBuffer, __in unsigned int ReadLength, __in__out unsigned int *pCheckSun)
{
unsigned int i;
unsigned int CheckSun;
unsigned int CurrentSun_1;
unsigned int CurrentSun_2;
unsigned int CurrentSun_sum;
unsigned int Byte;
if(0 == ReadLength)
{
return;
}
CurrentSun_2 = CurrentSun_1 = *pCheckSun;
CurrentSun_2 &= 0xffff;
CurrentSun_1 >>= 0x10;
CurrentSun_sum = CurrentSun_1;
for(i = 0; i < ReadLength; i++)
{
CurrentSun_1 = (unsigned int)(*(ReadBuffer + i));
Byte = CurrentSun_1 + CurrentSun_2;
CurrentSun_2 = Byte % 0xfff1;
CurrentSun_1 = CurrentSun_sum + CurrentSun_2;
CurrentSun_sum = CurrentSun_1 % 0xfff1;
}
*pCheckSun = (CurrentSun_sum << 0x10) + CurrentSun_2;
}
新版的autoit 搞不定 只能拿N年前的版本意淫了