📄 shubloadercore.cpp
字号:
//have just been performed.
ptc.orig=orig;
}
if(ptc.fcnCallBack!=NULL)
ptc.fcnCallBack(ptc.address);
if(!bDonotWrite) {
//Writes the modified bytes into the victim process
//takes all the required values from ptc (top of patches stack).
//the written bytes are placed into Patch::byteswritten
gsar.WriteProcessMemory(pi.hProcess,
(LPVOID)(ptc.address), (LPVOID)(&(ptc.patch)), 1,
&ptc.byteswritten);
if(ptc.byteswritten==0)
strlastError=GetLastErrorMsg();
else
strlastError=TextString("OK");
//Fill the report string of the current patch
char msg[MAX_PATH];
sprintf(msg, "%d)\toffset=%X\torig=%X\tpatch=%X\twritten=%d\tError=%s",
idx, ptc.address, ptc.orig, ptc.patch,
ptc.byteswritten, strlastError.c_str());
ptc.msg=TextString(msg);
}
#ifdef _DEBUG
//Add the report string of the last patch to the whole report string.
strFinalReport << ptc.msg << "\n";
#endif
//Eliminates the patch just elaborated from the patches stack
//Once the patch has been done and all the check are fine,
//there's no more need to store this item into the patches stack.
stkPatches.pop();
} //end patches for
if(!ActionsAfterGateProcedure()) {
CloseHandle(pi.hProcess);
throw BAD_ACTIONSAFTERGATEPROCEDURE;
}
//resume the patched process and exit from this loader.
if(bProcessOpened)
ZwResumeProcess(pi.hProcess);
else
ResumeThread(pi.hThread);
//Closes eventually open things, opened during the different trials to SuspendThread.
if(thPriority!=0)
SetThreadPriority(pi.hThread,thPriority);
if(bProcessOpened)
CloseHandle(pi.hProcess);
#ifdef _DEBUG
//writes the final report of the work done!
if(!m_SilentMode) {
::MessageBox(NULL,strFinalReport.c_str(), DEFAULT_MSG_CAPTION,
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
}
#endif
if(!stkErrors.empty()) {
::MessageBeep(-1);
printf("Sorry this version cannot be patched!\n");
while(!stkErrors.empty()) {
int idx=stkErrors.size();
TextString str=stkErrors.top();
stkErrors.pop();
printf("%d> %s\n", idx--, str.c_str());
}
}
break;
}
} //end while
if(!bProcessOpened)
CloseHandle(pi.hProcess);
if(!ActionsBeforeClosingLoader())
throw BAD_ACTIONSBEFORECLOSINGLOADER;
} //end try block
catch (int err) {
if(!m_SilentMode) {
if(err<0) {
char str[256];
sprintf(str, "Cannot Patch the program!\nInternal Error: %d\nSystem Error: %s",
err, GetLastErrorMsg().c_str() );
::MessageBox(NULL, str, DEFAULT_MSG_CAPTION, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
}
}
return err; //return the error to the caller
}
return 1; //all went fine!
}
//Translates into a TextString the last error occurred.
//This value is retrieved through the GetLastError system's function
TextString ShubLoaderCore::GetLastErrorMsg()
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
TextString msg;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
msg << "System error no." << (int)dw << ": \"" << (char*)lpMsgBuf << "\"\n";
LocalFree(lpMsgBuf);
return msg;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Reflection is a requirement for the official CRC-32 standard.
// You can create CRCs without it, but they won't conform to the standard.
ULONG ShubLoaderCore::Reflect(ULONG ref, char ch)
{// Used only by Init_CRC32_Table()
ULONG value(0);
// Swap bit 0 for bit 7
// bit 1 for bit 6, etc.
for(int i = 1; i < (ch + 1); i++)
{
if(ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
}
return value;
}
BOOL ShubLoaderCore::CRCFile(LPCSTR strfilename, DWORD storedCRC)
{
HANDLE hFile = CreateFile(strfilename,
GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
NULL);
if(hFile == INVALID_HANDLE_VALUE) {
if(!m_SilentMode) {
TextString str=GetLastErrorMsg();
::MessageBox(NULL, str.c_str(), DEFAULT_MSG_CAPTION,
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
}
return FALSE;
}
// Get the file size so we know how long to make our buffer.
DWORD filesize = GetFileSize(hFile,NULL);
// Create a CString buffer of the proper length
HGLOBAL hMem = GlobalAlloc(GHND, filesize);
LPVOID ptrMem = GlobalLock(hMem);
// Read the file into the buffer
DWORD bytesread=0;
ReadFile(hFile, ptrMem,filesize, &bytesread, NULL);
// We're done with the file handle so close it.
CloseHandle(hFile);
// Check to be sure we read the whole file.
if(bytesread!=filesize) {
if(!m_SilentMode) {
::MessageBox(NULL, "Wrong filesize", DEFAULT_MSG_CAPTION,
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
}
return FALSE;
}
DWORD calculatedCRC=0;
//////////////////////////////////////////////////////////////////////////
//Init_CRC32_Table
// This is the official polynomial used by CRC-32
// in PKZip, WinZip and Ethernet.
ULONG crc32_table[256]; // Lookup table array
ULONG ulPolynomial = 0x04c11db7;
// 256 values representing ASCII character codes.
for(int i = 0; i <= 0xFF; i++)
{
crc32_table[i]=Reflect(i, 8) << 24;
for (int j = 0; j < 8; j++)
crc32_table[i] = (crc32_table[i] << 1) ^ (crc32_table[i] & (1 << 31) ? ulPolynomial : 0);
crc32_table[i] = Reflect(crc32_table[i], 32);
}
// Be sure to use unsigned variables,
// because negative values introduce high bits
// where zero bits are required.
ULONG crc(0xffffffff);
int len;
unsigned char* buffer;
len = filesize;
buffer=(unsigned char*)ptrMem;
// Perform the algorithm on each character
// in the string, using the lookup table values.
while(len--)
crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *buffer++];
// Exclusive OR the result with the beginning value.
calculatedCRC = crc^0xffffffff;
//////////////////////////////////////////////////////////////////////////
if(calculatedCRC!=storedCRC) {
if(!m_SilentMode) {
::MessageBox(NULL, "Wrong file CRC", DEFAULT_MSG_CAPTION,
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
}
return FALSE;
}
//free up all the things
GlobalUnlock(hMem);
GlobalFree(ptrMem);
return TRUE;
}
void ShubLoaderCore::SetVictimCRC(DWORD crc)
{
m_bcheckCRC=TRUE;
m_dwVictimCRCValue=crc; //calculated using any crc calculator (eg use the one I supplied)
}
void ShubLoaderCore::SetCreateProcessFlags(DWORD dwFlags)
{
m_dwCreationFlags=dwFlags;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
int ShubLoaderCore::PushPatchVector(growing_arraystack<Patch> &stkPatches,
DWORD startAddr, BYTE *OriVector, BYTE *PatchVector, int dimension,
fcnPatchCallBack fcn )
{
if(startAddr==NULL || (OriVector==NULL && PatchVector==NULL) || PatchVector==NULL)
return -1; //not supplied valid data or PatchVector is NULL (it is mandatory)
int idx=0;
while(idx<dimension) {
Patch *ptc=NULL;
if(OriVector!=NULL) {
if( idx==dimension-1 && fcn!=NULL)
ptc=new Patch(startAddr+(DWORD)idx, (BYTE)(*(OriVector+idx)), (BYTE)(*(PatchVector+idx)), fcn);
else
ptc=new Patch(startAddr+(DWORD)idx, (BYTE)(*(OriVector+idx)), (BYTE)(*(PatchVector+idx)) );
}
else {
if( idx==dimension-1 && fcn!=NULL)
ptc=new Patch(startAddr+(DWORD)idx, (BYTE)(*(PatchVector+idx)), fcn);
else
ptc=new Patch(startAddr+(DWORD)idx, (BYTE)(*(PatchVector+idx)) );
}
stkPatches.push(*ptc);
delete ptc;
idx++;
}
return 0;
}
BOOL ShubLoaderCore::ReadProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer,
DWORD nSize, LPDWORD lpNumberOfBytesRead) {
BMG_gsar gsar;
return gsar.ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}
BOOL ShubLoaderCore::WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer,
DWORD nSize, LPDWORD lpNumberOfBytesWritten) {
BMG_gsar gsar;
return gsar.WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
}
void ShubLoaderCore::SetStartingMsg( TextString msg)
{
m_startingMsg = msg;
m_startingMsg << "\n";
}
void ShubLoaderCore::SetStartingMsg( char* msg)
{
m_startingMsg = TextString(msg);
m_startingMsg << "\n";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -