mirror of
https://github.com/dashr9230/SA-MP.git
synced 2024-12-22 14:37:29 +08:00
[saco] Implement and match file check functions
This commit is contained in:
parent
d86fdfc4eb
commit
0a59142702
128
saco/filechecks.cpp
Normal file
128
saco/filechecks.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include "filechecks.h"
|
||||
#include "filehooks.h"
|
||||
#include "../saco/filesystem.h"
|
||||
#include "../saco/archive/archivefs.h" // The new FileSystem
|
||||
#include "md5.h"
|
||||
|
||||
extern CFileSystem *pFileSystem;
|
||||
|
||||
DWORD WINAPI Arch_SetFilePointer( HANDLE hFile,LONG lDistanceToMove,
|
||||
PLONG lpDistanceToMoveHigh,DWORD dwMoveMethod );
|
||||
BOOL WINAPI Arch_ReadFile( HANDLE hFile,LPVOID lpBuffer,
|
||||
DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead,
|
||||
LPOVERLAPPED lpOverlapped );
|
||||
|
||||
BOOL IsCheckableFile(CHAR* szExt)
|
||||
{
|
||||
// Obfuscate the code in the dll slightly to make tracing it harder
|
||||
// very hard coded and messy but should detect ide and ipl case insensitively
|
||||
if ((*szExt++ & 0xDF) != 'I') return FALSE;
|
||||
if ((*szExt | 0x20) + 7 != 'k')
|
||||
{
|
||||
if ((*szExt & 0xDF) - 17 == '?')
|
||||
{
|
||||
szExt++;
|
||||
if (((*szExt | 0x20) - 'k') == 1) return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((*++szExt & 0xDF) - 'E')) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CheckFileHash(int dwFileHash, HANDLE hFile)
|
||||
{
|
||||
DWORD dwFileIndex = ((CArchiveFS*)pFileSystem)->GetFileIndex(0xa848b69a);
|
||||
|
||||
if (dwFileIndex != FS_INVALID_FILE)
|
||||
{
|
||||
BYTE *pbData = pFileSystem->GetFileData(dwFileIndex);
|
||||
BYTE byteCount = *pbData++; // Get and jump over header
|
||||
|
||||
// Search the tree
|
||||
BOOL bFound = FALSE;
|
||||
BYTE i = 0;
|
||||
BINARY_TREE* pItem;
|
||||
|
||||
while(!bFound && i < byteCount)
|
||||
{
|
||||
pItem = (BINARY_TREE*)(pbData + (i * sizeof (BINARY_TREE)));
|
||||
if (pItem->dwFileHash == dwFileHash)
|
||||
{
|
||||
i = pItem->byteData;
|
||||
bFound = TRUE;
|
||||
}
|
||||
else if (pItem->dwFileHash < dwFileHash)
|
||||
{
|
||||
i = pItem->byteRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = pItem->byteLeft;
|
||||
}
|
||||
}
|
||||
#ifndef _DEBUG
|
||||
if (i >= byteCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Jump over the header and tree blocks into the data block
|
||||
MD5_DATA* mdHash = (MD5_DATA*)(pbData + (byteCount * sizeof (BINARY_TREE)) + (i * sizeof (MD5_DATA)));
|
||||
|
||||
DWORD dwWasRead;
|
||||
BYTE szBuffer[1024];
|
||||
|
||||
MD5_CTX mdCTX;
|
||||
MD5Init(&mdCTX);
|
||||
DWORD dwDataToRead = 1024;
|
||||
|
||||
while (Arch_ReadFile(hFile, (LPVOID)szBuffer, dwDataToRead, &dwWasRead, NULL) && dwWasRead)
|
||||
{
|
||||
MD5Update(&mdCTX, szBuffer, dwWasRead);
|
||||
}
|
||||
|
||||
BYTE byteDigest[16];
|
||||
MD5Final(byteDigest, &mdCTX);
|
||||
|
||||
LONG lDistanceHigh = 0;
|
||||
Arch_SetFilePointer(hFile, 0, &lDistanceHigh, FILE_BEGIN);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if ((BYTE)byteDigest[i] != (BYTE)mdHash->byteData[i])
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GetFileNameHash(char* szFileName)
|
||||
{
|
||||
// Based on a Jenkins hash
|
||||
int dwHash = 0;
|
||||
char* len = strlen(szFileName) + szFileName;
|
||||
while (szFileName < len)
|
||||
{
|
||||
char c = *szFileName;
|
||||
dwHash += (c > 'Z' || c < 'A') ? (c) : (c | 0x20); // Lower case
|
||||
dwHash += (dwHash << 10);
|
||||
dwHash ^= (dwHash >> 6);
|
||||
szFileName++;
|
||||
}
|
||||
dwHash += (dwHash << 3);
|
||||
dwHash ^= (dwHash >> 11);
|
||||
dwHash += (dwHash << 15);
|
||||
return dwHash;
|
||||
}
|
18
saco/filechecks.h
Normal file
18
saco/filechecks.h
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
typedef struct _BIN_TREE
|
||||
{
|
||||
int dwFileHash;
|
||||
BYTE byteLeft;
|
||||
BYTE byteRight;
|
||||
BYTE byteData;
|
||||
BYTE bytePadding;
|
||||
} BINARY_TREE;
|
||||
|
||||
typedef struct _MD5_DATA
|
||||
{
|
||||
BYTE byteData[16];
|
||||
} MD5_DATA;
|
||||
|
||||
BOOL IsCheckableFile(CHAR* szExt);
|
||||
void CheckFileHash(int dwFileHash, HANDLE hFile);
|
||||
int GetFileNameHash(char* szFileName);
|
@ -703,6 +703,12 @@
|
||||
<File
|
||||
RelativePath=".\fhicl-sha1.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filechecks.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filechecks.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filehooks.cpp">
|
||||
</File>
|
||||
|
Loading…
Reference in New Issue
Block a user