void init_search_context(Search_Context *context, const void *data, int length) { context->position = 0; context->data = (const char*)data; context->length = length; context->chains = M_ALLOC(Search_Chain, SEARCH_CHAIN_COUNT); context->chain_data = M_ALLOC(uint16_t, SEARCH_DATA_COUNT); // TODO: Free list optimization (less GC) // Initialize the null-chain context->chain_data[0] = 0xFFFF; context->chain_data_head = 1; // Initialize all the chains to be too far away to reference (not seen yet) Search_Chain *chains = context->chains; for (unsigned i = 0; i < SEARCH_CHAIN_COUNT; i++) { chains[i].base = -SEARCH_MAX_DIST; } context->last_end_chain = 0; context->last_match_length = 0; context->last_match_was_best = 0; }
//-------------------------------------------------------------------------------------- void DbgMsg(char *lpszFile, int iLine, char *lpszMsg, ...) { va_list mylist; va_start(mylist, lpszMsg); int len = _vscprintf(lpszMsg, mylist) + 0x100; char *lpszBuff = (char *)M_ALLOC(len); if (lpszBuff == NULL) { va_end(mylist); return; } char *lpszOutBuff = (char *)M_ALLOC(len); if (lpszOutBuff == NULL) { M_FREE(lpszBuff); va_end(mylist); return; } vsprintf_s(lpszBuff, len, lpszMsg, mylist); va_end(mylist); sprintf_s(lpszOutBuff, len, "%s(%d) : %s", lpszFile, iLine, lpszBuff); OutputDebugString(lpszOutBuff); HANDLE hStd = GetStdHandle(STD_OUTPUT_HANDLE); if (hStd != INVALID_HANDLE_VALUE) { DWORD dwWritten = 0; WriteFile(hStd, lpszBuff, strlen(lpszBuff), &dwWritten, NULL); } if (m_hDbgFile && m_hDbgFileMutex) { sprintf_s(lpszOutBuff, len, "%s", lpszBuff); WaitForSingleObject(m_hDbgFileMutex, INFINITE); DWORD dwWritten; SetFilePointer(m_hDbgFile, 0, NULL, FILE_END); WriteFile(m_hDbgFile, lpszOutBuff, strlen(lpszOutBuff), &dwWritten, NULL); ReleaseMutex(m_hDbgFileMutex); } M_FREE(lpszBuff); M_FREE(lpszOutBuff); }
// Since the chains are dynamically allocated in a buffer it can run out of space. // In this case we run a garbage collection, which frees all the unreachable // chain nodes and unused memory. // Returns the amount of the used space of the `chain_data` buffer. unsigned chain_data_gc(Search_Chain *chains, unsigned chain_count, uint16_t *chain_data, unsigned chain_data_count, int pos) { Live_Chain *live_chains = M_ALLOC(Live_Chain, chain_count); unsigned live_chain_count = 0; int drop_at = pos - SEARCH_MAX_DIST; for (unsigned i = 0; i < chain_count; i++) { Search_Chain *chain = &chains[i]; chain->capacity = 0; int chain_pos = chain->base; int chain_data_index = chain->data_index; uint16_t *start = &chain_data[chain_data_index]; uint16_t *iter = start; // Follow the chain as far as possible while (chain_pos >= drop_at) { chain_pos -= *iter++; } // Length is one shorter since the last one is always the terminator. int length = (int)(iter - start - 1); // If there are not enough dynamic nodes we can point it at the null chain. if (length <= 0) { chain->data_index = 0; continue; } // Keep the chain Live_Chain *live_chain = &live_chains[live_chain_count++]; live_chain->chain_index = i; live_chain->data_index = chain_data_index; live_chain->data_length = length; } // Leave null index at 0. unsigned data_index = 1; // If the chains are sorted then when copying the live ones there is no need // for an extra buffer since the elements always shrink there is never the // danger of overwriting other live chains. qsort(live_chains, live_chain_count, sizeof(Live_Chain), &live_chain_compare); for (unsigned i = 0; i < live_chain_count; i++) { Live_Chain *live = &live_chains[i]; Search_Chain *chain = &chains[live->chain_index]; memcpy(&chain_data[data_index], &chain_data[live->data_index], live->data_length * sizeof(uint16_t)); // The chains always end with a terminator, but it's not counted in length. chain_data[live->data_index + live->data_length] = 0xFFFF; chain->data_index = data_index; data_index += live->data_length + 1; } return data_index; }
void DoW2SMailSendResult( CMessage *pMsg ) { long lRet=0; BYTE *ByteData = NULL; CPlayer *pPlayer=NULL; CGUID WriterGuid; pMsg->GetGUID(WriterGuid); lRet = pMsg->GetLong(); long lByteDataLen = pMsg->GetLong(); if (lRet==1) { ByteData = (BYTE*)M_ALLOC(sizeof(BYTE)*lByteDataLen); pMsg->GetEx(ByteData,lByteDataLen); long Pos = 0; tagMailParam *pMailParam = OBJ_CREATE(tagMailParam); GameManager::GetInstance()->GetMailManager()->DecordMailMsgFromByteArray(ByteData,Pos,pMailParam); CMail *pMail = OBJ_CREATE_PVOID(CMail, (void*)pMailParam); pPlayer = GetGame()->FindPlayer(pMail->GetWriter().c_str()); if (pPlayer) { int nRet = GameManager::GetInstance()->GetMailManager()->ReMoveGoldAndGoods(pMail,pPlayer);//--扣除物品和金钱 GameManager::GetInstance()->GetMailManager()->SendMailToReceiver(pMail->GetExID(),nRet); } OBJ_RELEASE(CMail, pMail); M_FREE(ByteData, sizeof(BYTE)*lByteDataLen); } else { GameManager::GetInstance()->GetMailManager()->SendMailFailedToClient(WriterGuid,MAIL_SENDING_FAILED_INVALID_RECEIVER);//--非法收信人 } }
AinMessage* AinMessage::Create(LONG lType) { AinMessage* pRe = (AinMessage*)M_ALLOC(sizeof(AinMessage)); if(NULL != pRe) new(pRe)AinMessage(lType); return pRe; }
//-------------------------------------------------------------------------------------- PVOID GetSysInf(SYSTEM_INFORMATION_CLASS InfoClass) { NTSTATUS ns = 0; ULONG RetSize = 0, Size = 0x100; PVOID Info = NULL; GET_NATIVE(NtQuerySystemInformation); while (true) { // allocate memory for system information if ((Info = M_ALLOC(Size)) == NULL) { DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n"); return NULL; } // query information RetSize = 0; ns = f_NtQuerySystemInformation(InfoClass, Info, Size, &RetSize); if (ns == STATUS_INFO_LENGTH_MISMATCH) { // buffer is too small M_FREE(Info); Info = NULL; if (RetSize > 0) { // allocate more memory and try again Size = RetSize + 0x100; } else { break; } } else { break; } } if (!NT_SUCCESS(ns)) { DbgMsg(__FILE__, __LINE__, "NtQuerySystemInformation() fails; status: 0x%.8x\n", ns); if (Info) { M_FREE(Info); } return NULL; } return Info; }
void DoW2SMailReceive( CMessage *pMsg ) { BYTE *ByteData = NULL; list<CGUID> lMailGuid; list<CMail*> lMailList; CGUID playerGuid; pMsg->GetGUID(playerGuid); long lByteDataLen = pMsg->GetLong(); ByteData = (BYTE*)M_ALLOC(sizeof(BYTE)*lByteDataLen); pMsg->GetEx(ByteData,lByteDataLen); time_t t_CurrentTime = time(NULL); CPlayer *pPlayer = GetGame()->FindPlayer(playerGuid); if (pPlayer) { long Pos = 0; long lNum = _GetLongFromByteArray(ByteData,Pos); for (int i=0; i<lNum; ++i) { tagMailParam *pMailParam = OBJ_CREATE(tagMailParam); GameManager::GetInstance()->GetMailManager()->DecordFromByteArray(ByteData,Pos,pMailParam); CMail *pMail = OBJ_CREATE_PVOID(CMail, (void*)pMailParam); if(!GameManager::GetInstance()->GetMailManager()->SetMapMail(pMail)) { lMailGuid.push_back(pMailParam->guid); } else { lMailList.push_back(pMail); } } if(lMailGuid.size()>0) { //删除邮件 GameManager::GetInstance()->GetMailManager()->DeleteMailToWS(lMailGuid,pPlayer); } vector<BYTE> vectorByte; vectorByte.clear(); _AddToByteArray(&vectorByte,(long)lMailList.size()); pPlayer->SetReceiveMail(true); for (list<CMail*>::iterator it=lMailList.begin();it!=lMailList.end();++it) { pPlayer->AddReceiveMailList((*it)->GetExID()); } GameManager::GetInstance()->GetMailManager()->SendReceiveMail( pPlayer ); } M_FREE(ByteData, lByteDataLen); }
//! 添加一个硬件信息节点 BOOL HardInfoList::AddNode(tagHardwareInfo &HardwareInfo, BOOL bSendToUser) { if(NULL == m_CurrGroup.pHardwareInfo) { m_CurrGroup.pHardwareInfo = (tagHardwareInfo*)M_ALLOC(sizeof(tagHardwareInfo) * HARD_INFO_GROUP_NUM); m_CurrGroup.dwUseNum = 0; if (NULL == m_CurrGroup.pHardwareInfo) { return FALSE; } } if(HARD_INFO_GROUP_NUM <= m_CurrGroup.dwUseNum) { AddGroup(m_CurrGroup); m_CurrGroup.dwUseNum = 0; m_CurrGroup.pHardwareInfo = (tagHardwareInfo*)M_ALLOC(sizeof(tagHardwareInfo) * HARD_INFO_GROUP_NUM); if (NULL == m_CurrGroup.pHardwareInfo) { return FALSE; } } m_CurrGroup.pHardwareInfo[m_CurrGroup.dwUseNum] = HardwareInfo; ++m_CurrGroup.dwUseNum; if(bSendToUser) { CMessage msg(MSG_SCC2SUC_INFO_Notify_AddHardInfo); DBWriteSet setWriteSet; msg.GetDBWriteSet(setWriteSet); setWriteSet.AddToByteArray(m_dwSMID); setWriteSet.AddToByteArray(&HardwareInfo, sizeof(tagHardwareInfo)); UserManage::GetInstance().SendToAll(ePT_Penniless, msg); } return TRUE; }
void CQuestionManager::UpdateQuestions( DBReadSet &db ) { ClearQuestions(); long lCount = db.GetLongFromByteArray(); m_Questions.reserve( lCount ); for( long i = 0; i < lCount; ++ i ) { Question ques; ques.answer = db.GetByteFromByteArray(); ques.data.size = (size_t) db.GetLongFromByteArray(); ques.data.buf = M_ALLOC( sizeof(char)*(ques.data.size) ); db.GetBufferFromByteArray( ques.data.buf, ques.data.size ); m_Questions.push_back( ques ); } }
//-------------------------------------------------------------------------------------- BOOL DbgInit(char *lpszDbgLogPath) { m_hDbgFile = NULL; m_hDbgFileMutex = NULL; if (m_hDbgFileMutex = CreateMutexA(NULL, FALSE, DBG_MUTEX_NAME)) { if ((m_hDbgFile = CreateFileA( lpszDbgLogPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) { // OK SetFilePointer(m_hDbgFile, 0, NULL, FILE_END); const unsigned int len = 30; DWORD dwWritten = 0; char *lpszBuff = (char *)M_ALLOC(len); if (lpszBuff == NULL) return FALSE; SYSTEMTIME time; GetLocalTime(&time); sprintf_s(lpszBuff, len, "Dbg initialized %02d.%02d %02d:%02d\n", time.wDay, time.wMonth,time.wHour,time.wMinute); WriteFile(m_hDbgFile, lpszBuff, strlen(lpszBuff), &dwWritten, NULL); M_FREE(lpszBuff); return TRUE; } else { DbgMsg(__FILE__, __LINE__, "CreateFile() ERROR %d\n", GetLastError()); } CloseHandle(m_hDbgFileMutex); m_hDbgFile = NULL; m_hDbgFileMutex = NULL; } else { DbgMsg(__FILE__, __LINE__, "CreateMutex() ERROR %d\n", GetLastError()); } return FALSE; }
//-------------------------------------------------------------------------------------- BOOL ConfGetNodeAttributeW(IXMLDOMNode *pIDOMNode, PWSTR name, PWSTR *value) { BOOL bRet = FALSE; IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL; // query attributes map HRESULT hr = pIDOMNode->get_attributes(&pIXMLDOMNamedNodeMap); if (SUCCEEDED(hr) && pIXMLDOMNamedNodeMap) { IXMLDOMNode *pIDOMAttrNode = NULL; // query attribute node hr = pIXMLDOMNamedNodeMap->getNamedItem(name, &pIDOMAttrNode); if (SUCCEEDED(hr) && pIDOMAttrNode) { VARIANT varValue; hr = pIDOMAttrNode->get_nodeValue(&varValue); if (FAILED(hr)) { DbgMsg(__FILE__, __LINE__, "pIDOMAttrNode->get_nodeValue() ERROR 0x%.8x\n", hr); goto free; } BSTR val = _bstr_t(varValue); DWORD Len = (wcslen((PWSTR)val) + 1) * sizeof(WCHAR); if (*value = (PWSTR)M_ALLOC(Len)) { ZeroMemory(*value, Len); wcscpy(*value, (PWSTR)val); bRet = TRUE; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() ERROR %d\n", GetLastError()); } free: pIDOMAttrNode->Release(); pIDOMAttrNode = NULL; } pIXMLDOMNamedNodeMap->Release(); pIXMLDOMNamedNodeMap = NULL; } return bRet; }
double CScript::TestLog(const char* CmdStr, char* retStr) { DWORD time = timeGetTime(); char tt[32]; ultoa(time, tt, 10); long lRet1 = strlen(CmdStr); long lRet2 = strlen(tt); char* ptr = (char*)M_ALLOC(lRet1 + lRet2 + 2); strcpy_s(ptr, lRet1 + lRet2 + 2, tt); strcat_s(ptr, lRet1 + lRet2 + 2, ":"); strcat_s(ptr, lRet1 + lRet2 + 2, CmdStr); if (ptr) { PutDebugString(ptr); M_FREE(ptr, lRet1 + lRet2 + 2); } return 1; }
double CScript::If(const char* CmdStr, char* retStr) { CScript *pTemptScript = PopFreeScript(CmdStr); InitChildScriptData(pTemptScript); long len = lstrlen(CmdStr); char* str = (char*)M_ALLOC(sizeof(char)*(len+1)); memcpy(str, &CmdStr[3], len-4); str[len-4] = ';'; str[len-3] = 0; //设置变量 pTemptScript->SetVariableList(m_pVariableList); pTemptScript->RunLine(str); M_FREE(str, len+1); double dbRet = pTemptScript->m_Value[0]; PushFreeScript(pTemptScript); return dbRet; }
void DoW2SMailSend( CMessage *pMsg ) { BYTE *ByteData = NULL; CGUID MailGuid; pMsg->GetGUID(MailGuid); long lByteDataLen = pMsg->GetLong(); ByteData = (BYTE*)M_ALLOC(sizeof(BYTE)*lByteDataLen); pMsg->GetEx(ByteData,lByteDataLen); long Pos = 0; tagMailParam *pMailParam = OBJ_CREATE(tagMailParam); GameManager::GetInstance()->GetMailManager()->DecordFromByteArray(ByteData,Pos,pMailParam); CMail *pMail = OBJ_CREATE_PVOID(CMail, (void*)pMailParam);//用pMailParam作为构造函数创建CMail对象 GameManager::GetInstance()->GetMailManager()->SendMailToClient(pMail); M_FREE(ByteData, sizeof(BYTE)*lByteDataLen); }
//-------------------------------------------------------------------------------------- BOOL ConfGetNodeAttributeA(IXMLDOMNode *pIDOMNode, PWSTR name, PCHAR *value) { BOOL bRet = FALSE; PWSTR value_w; if (ConfGetNodeAttributeW(pIDOMNode, name, &value_w)) { int len = wcslen(value_w); if (*value = (PCHAR)M_ALLOC(len + 1)) { ZeroMemory(*value, len + 1); WideCharToMultiByte(CP_ACP, 0, value_w, -1, *value, len, NULL, NULL); bRet = TRUE; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() ERROR %d\n", GetLastError()); } M_FREE(value_w); } return bRet; }
/** * получение значения узла * @param pIDOMNode дескриптор узла * @param str адресс unicode-строки, в которую будет записано значение * @return TRUE если всё ОК, FALSE в случае ошибки * @see ConfGetListNodeByName() * @see ConfGetNodeByName() * @see ConfGetTextByName() */ BOOL ConfGetNodeTextA(IXMLDOMNode *pIDOMNode, PCHAR *str) { BOOL bRet = FALSE; PWSTR str_w; if (ConfGetNodeTextW(pIDOMNode, &str_w)) { int len = wcslen(str_w); if (*str = (PCHAR)M_ALLOC(len + 1)) { ZeroMemory(*str, len + 1); WideCharToMultiByte(CP_ACP, 0, str_w, -1, *str, len, NULL, NULL); bRet = TRUE; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() ERROR %d\n", GetLastError()); } M_FREE(str_w); } return bRet; }
/** * получение значения узла * @param pIDOMNode дескриптор узла * @param str адресс unicode-строки, в которую будет записано значение * @return TRUE если всё ОК, FALSE в случае ошибки * @see ConfGetListNodeByName() * @see ConfGetNodeByName() * @see ConfGetTextByName() */ BOOL ConfGetNodeTextW(IXMLDOMNode *pIDOMNode, PWSTR *str) { BOOL bRet = FALSE; BSTR val = NULL; if (pIDOMNode == NULL) { return FALSE; } HRESULT hr = pIDOMNode->get_text(&val); if (FAILED(hr)) { DbgMsg(__FILE__, __LINE__, "pIDOMNode->get_text() ERROR 0x%.8x\n", hr); return FALSE; } DWORD Len = (wcslen((PWSTR)val) + 1) * sizeof(WCHAR); if (*str = (PWSTR)M_ALLOC(Len)) { ZeroMemory(*str, Len); wcscpy_s(*str, Len / sizeof(wchar_t), (PWSTR)val); bRet = TRUE; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() ERROR %d\n", GetLastError()); } if (val) { SysFreeString(val); } return bRet; }
//-------------------------------------------------------------------------------------- PVOID Hook(PVOID Function, PVOID Handler, PULONG pBytesPatched) { #ifdef _X86_ #define SIZEOFJUMP 6 #elif _AMD64_ #define SIZEOFJUMP 14 #endif ULONG Size = 0, CollectedSpace = 0; PUCHAR pInst = (PUCHAR)Function; if (pBytesPatched) { *pBytesPatched = NULL; } // initialize disassembler engine ud_t ud_obj; ud_init(&ud_obj); // set mode, syntax and vendor ud_set_mode(&ud_obj, UD_MODE); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_vendor(&ud_obj, UD_VENDOR_INTEL); while (CollectedSpace < SIZEOFJUMP) { ud_set_input_buffer(&ud_obj, pInst, MAX_INST_LEN); // get length of instruction ULONG dwInstLen = ud_disassemble(&ud_obj); if (dwInstLen == 0) { // error while disassembling instruction DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: Can't disassemble instruction at "IFMT"\n", pInst); return NULL; } if (ud_obj.mnemonic == UD_Ijmp || ud_obj.mnemonic == UD_Icall) { // call/jmp with relative address DbgMsg(__FILE__, __LINE__, __FUNCTION__"() call/jmp/jxx instruction at "IFMT"\n", pInst); return NULL; } for (int i = 0; i < 3; i++) { if (ud_obj.operand[i].type == UD_OP_JIMM) { // jxx with relative address DbgMsg(__FILE__, __LINE__, __FUNCTION__"() jxx instruction at "IFMT"\n", pInst); return NULL; } } pInst += dwInstLen; CollectedSpace += dwInstLen; if (ud_obj.mnemonic == UD_Iret || ud_obj.mnemonic == UD_Iretf || ud_obj.mnemonic == UD_Iiretw || ud_obj.mnemonic == UD_Iiretq || ud_obj.mnemonic == UD_Iiretd) { // end of the function thunk? DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ret/retn/iret instruction at "IFMT"\n", pInst); break; } } if (SIZEOFJUMP > CollectedSpace) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: not enough memory for jump\n"); return NULL; } ULONG CallGateSize = CollectedSpace + SIZEOFJUMP; // allocate memory for callgate PVOID CallGate = M_ALLOC(CallGateSize); if (CallGate) { // generate callgate memset(CallGate, 0x90, CallGateSize); // save begining of the function memcpy(CallGate, Function, CollectedSpace); #ifdef _X86_ // jump from callgate to function body // push imm32 *(PUCHAR)((PUCHAR)CallGate + CollectedSpace) = 0x68; *(PUCHAR *)((PUCHAR)CallGate + CollectedSpace + 1) = (PUCHAR)Function + SIZEOFJUMP; // ret *(PUCHAR)((PUCHAR)CallGate + CollectedSpace + 5) = 0xC3; #elif _AMD64_ // jmp qword [addr] *(PUSHORT)((PUCHAR)CallGate + CollectedSpace) = 0x25FF; *(PULONG)((PUCHAR)CallGate + CollectedSpace + 2) = 0; // addr dq XXXh *(PULONGLONG)((PUCHAR)CallGate + CollectedSpace + 6) = (ULONGLONG)Function + SIZEOFJUMP; #endif // jump from the function to callgate memset(Function, 0x90, CollectedSpace); #ifdef _X86_ // push imm32 *(PUCHAR)Function = 0x68; *(PUCHAR *)((PUCHAR)Function + 1) = (PUCHAR)Handler; // ret *(PUCHAR)((PUCHAR)Function + 5) = 0xC3; #elif _AMD64_ // jmp qword [addr] *(PUSHORT)Function = 0x25FF; *(PULONG)((PUCHAR)Function + 2) = 0; // addr dq XXXh *(PULONGLONG)((PUCHAR)Function + 6) = (ULONGLONG)Handler; #endif *pBytesPatched = CollectedSpace; return CallGate; } else { DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n"); } return NULL; }
//-------------------------------------------------------------------------------------- int _tmain(int argc, _TCHAR* argv[]) { m_hInstance = (HINSTANCE)GetModuleHandle(NULL); if (argc >= 3) { m_lpFontPath = argv[2]; m_lpFontName = argv[1]; printf(__FUNCTION__"(): Using external font %ws \"%ws\"\n", m_lpFontName, m_lpFontPath); } else { printf("USAGE: MsFontsFuzz.exe <font_name> <font_file> [options]\n"); goto end; } _stprintf_s(m_TmpFontPath, _T("__TMP__%s"), _tGetNameFromFullPath(m_lpFontPath)); DbgMsg(__FILE__, __LINE__, "[+] Temporary font file is \"%ws\"\n", m_TmpFontPath); if (_tcslen(m_TmpFontPath) >= 4) { _tcslwr(m_TmpFontPath + _tcslen(m_TmpFontPath) - 4); if (!_tcscmp(m_TmpFontPath + _tcslen(m_TmpFontPath) - 4, _T(".otf"))) { m_dwFontType = FONT_TYPE_OTF; DbgMsg(__FILE__, __LINE__, "[+] Font type is .OTF\n"); } else if (!_tcscmp(m_TmpFontPath + _tcslen(m_TmpFontPath) - 4, _T(".ttf"))) { m_dwFontType = FONT_TYPE_TTF; DbgMsg(__FILE__, __LINE__, "[+] Font type is .TTF\n"); } } RemoveFontResource(m_TmpFontPath); #ifdef USE_BOADCAST_MESSAGES SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); #endif char ch = 0; memset(m_szTable, '.', sizeof(m_szTable) - 1); for (int i = 0; i < sizeof(m_szTable); i++) { if (i != 0 && i % 16 == 0) { m_szTable[i] = '\n'; continue; } if (ch >= 0x20) { m_szTable[i] = ch; } if (ch == 0x7f) { m_szTable[i] = 0; break; } ch += 1; } if (argc > 3) { // enumerate additional parameters for (int i = 3; i < argc; i++) { if (!_tcscmp(argv[i], _T("--test"))) { // single launch mode m_bTest = TRUE; } else if (!_tcscmp(argv[i], _T("--resume"))) { // resume fuzzing in the new process m_bResume = TRUE; } else if (!_tcscmp(argv[i], _T("--noisy"))) { // show lot of output information m_bNoisy = TRUE; } else if (!_tcscmp(argv[i], _T("--text")) && argc - i > 1) { #ifdef UNICODE // use caller-specified text for display WideCharToMultiByte( CP_ACP, 0, argv[i + 1], -1, m_szTable, sizeof(m_szTable) - 1, NULL, NULL ); #else strcpy_s(m_szTable, argv[i + 1]); #endif i++; } else if (!_tcscmp(argv[i], _T("--fix-crcs"))) { // fix incorrect checksums for the original font file m_bFixCrcs = TRUE; } else if (argc - i > 1 && argv[i][0] == '-') { /** * Process data generation options. */ LPCTSTR lpParam = argv[i] + 1; DWORD dwValue = 0; BOOL bFound = FALSE; if (!StrToIntEx(argv[i + 1], STIF_SUPPORT_HEX, (int *)&dwValue)) { DbgMsg(__FILE__, __LINE__, "[!] ERROR: Invalid value for parameter \"%ws\"\n", argv[i]); continue; } for (int i_n = 0; i_n < sizeof(m_Params) / sizeof(ENGINE_PARAM); i_n++) { // search parameter by name if (!_tcscmp(m_Params[i_n].lpName, lpParam)) { *(m_Params[i_n].pdwValue) = dwValue; bFound = TRUE; break; } } if (!bFound) { DbgMsg(__FILE__, __LINE__, "[!] ERROR: Unknown parameter \"%ws\"\n", argv[i]); } i++; } } } DbgInit(LOG_FILE_NAME); // check block size and range if (BLOCK_SIZE == 1) { if (BLOCK_RANGE_START >= 0xFF) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_START value (it must be <0xFF)\n"); goto end; } if (BLOCK_RANGE_END > 0xFF) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_END value (it must be <=0xFF)\n"); goto end; } } else if (BLOCK_SIZE == 2) { if (BLOCK_RANGE_START >= 0xFFFF) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_START value (it must be <0xFFFF)\n"); goto end; } if (BLOCK_RANGE_END > 0xFFFF) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_END value (it must be <=0xFFFF)\n"); goto end; } } else if (BLOCK_SIZE == 4) { if (BLOCK_RANGE_START >= 0xFFFFFFFF) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_START value (it must be <0xFFFFFFFF)\n"); goto end; } if (BLOCK_RANGE_END > 0xFFFFFFFF) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_END value (it must be <=0xFFFFFFFF)\n"); goto end; } } else { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_SIZE value (it must be 1, 2 or 4)\n"); goto end; } // check step size if (BLOCK_RANGE_N > BLOCK_RANGE_END) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_N value (it must be <=BLOCK_RANGE_END)\n"); goto end; } WNDCLASSEX wcex; ZeroMemory(&wcex, sizeof(wcex)); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.hInstance = m_hInstance; wcex.lpszClassName = _T(WND_CLASS); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); m_hWndEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (m_hWndEvent == NULL) { DbgMsg(__FILE__, __LINE__, "CreateEvent() ERROR %d\n", GetLastError()); goto end; } // register window class if (RegisterClassEx(&wcex) == NULL) { DbgMsg(__FILE__, __LINE__, "RegisterClassEx() ERROR %d\n", GetLastError()); goto end; } // init random number generator init_genrand(GetTickCount()); SetUnhandledExceptionFilter(UnhandledExceptionError); // read input file if (ReadFromFile(m_lpFontPath, &m_pData, &m_dwDataSize)) { if (FILE_RANGE_START >= m_dwDataSize) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid FILE_RANGE_START value (it must be <=FILE_SIZE)\n"); M_FREE(m_pData); return -1; } if (FILE_RANGE_END > m_dwDataSize) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid FILE_RANGE_END value (it must be <FILE_SIZE)\n"); M_FREE(m_pData); return -1; } if (FILE_RANGE_END == 0) { FILE_RANGE_END = m_dwDataSize; } if (FILE_RANGE_START >= FILE_RANGE_END) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid FILE_RANGE_START/FILE_RANGE_END values\n"); M_FREE(m_pData); return -1; } DbgMsg(__FILE__, __LINE__, "[+] %d bytes readed from \"%ws\"\n", m_dwDataSize, m_lpFontPath); if (!m_bResume && (m_dwFontType == FONT_TYPE_OTF || m_dwFontType == FONT_TYPE_TTF)) { OTF_TableByOffset(m_pData, (ULONG)-1); } if (m_bFixCrcs) { // write fixed checksums into the original file if (DumpToFile(m_lpFontPath, m_pData, m_dwDataSize)) { DbgMsg(__FILE__, __LINE__, "[+] Checksums has been fixed for font file \"%ws\"\n", m_lpFontPath); } } else if (m_bTest) { // single run with the unchanged font file if (DumpToFile(m_TmpFontPath, m_pData, m_dwDataSize)) { FuzzIteration(); } } else { DbgMsg(__FILE__, __LINE__, "[+] Fuzzing params:\n\n"); // print parameters values for (int i_n = 0; i_n < sizeof(m_Params) / sizeof(ENGINE_PARAM); i_n++) { DbgMsg(__FILE__, __LINE__, " %20ws = 0x%.8x\n", m_Params[i_n].lpName, *(m_Params[i_n].pdwValue)); } DbgMsg(__FILE__, __LINE__, "\n"); DbgMsg(__FILE__, __LINE__, "[+] Processing cases...\n\n"); // align buffer size by block size m_dwAlignedDataSize = XALIGN_UP(m_dwDataSize, BLOCK_SIZE); // allocate output buffer if (m_pAlignedData = M_ALLOC(m_dwAlignedDataSize)) { char *lpszBigBuff = (char *)M_ALLOC(BIG_BUFFER_LENGTH); if (lpszBigBuff) { FillMemory(lpszBigBuff, BIG_BUFFER_LENGTH, 'A'); } PVOID pBigData = M_ALLOC(m_dwDataSize + BIG_BUFFER_LENGTH); // for each byte/word/dword of input file... for (DWORD i = FILE_RANGE_START; i < FILE_RANGE_END; i += BLOCK_SIZE) { DbgMsg(__FILE__, __LINE__, "Offset=0x%.8x TotalSize=0x%.8x File=%.8x\n", i, m_dwDataSize, m_dwCasesProcessed); POTF_TABLE_HEADER Table = NULL; if (m_dwFontType == FONT_TYPE_OTF || m_dwFontType == FONT_TYPE_TTF) { Table = OTF_TableByOffset(m_pData, i); if (Table == NULL) { // skip OTF/TTF data outside the tables continue; } } if (BLOCK_RANGE_N > 0) { // fuze each value with the step size == BLOCK_RANGE_N for (DWORD n = XALIGN_DOWN(BLOCK_RANGE_START, BLOCK_RANGE_N); n < XALIGN_DOWN(BLOCK_RANGE_END, BLOCK_RANGE_N); n += BLOCK_RANGE_N) { // write plain value WriteVal(i, BLOCK_SIZE, n, n, n); if (BLOCK_SIZE > 1) { // write randomized value WriteVal(i, BLOCK_SIZE, n, n + getrand(0, BLOCK_RANGE_N - 1), n + getrand(0, BLOCK_RANGE_N - 1) ); } } } // zero-bytes stuff WriteVal(i, BLOCK_SIZE, 0x00, 0x0000, 0x00000000); // integer overflow stuff WriteVal(i, BLOCK_SIZE, 0xFF, 0xFFFF, 0xFFFFFFFF); // invalid user-mode pointers WriteVal(i, BLOCK_SIZE, 0x0D, 0x0D0D, 0x0D0D0D0D); if (lpszBigBuff && pBigData) { /** * Write big ASCI data after the each byte. */ memcpy(pBigData, m_pData, i); memcpy((PUCHAR)pBigData + i, lpszBigBuff, BIG_BUFFER_LENGTH); memcpy((PUCHAR)pBigData + i + BIG_BUFFER_LENGTH, (PUCHAR)m_pData + i, m_dwDataSize - i); if (m_dwFontType == FONT_TYPE_OTF || m_dwFontType == FONT_TYPE_TTF) { POTF_FILE_HEADER Hdr = (POTF_FILE_HEADER)pBigData; POTF_TABLE_HEADER Table = (POTF_TABLE_HEADER)((PUCHAR)pBigData + sizeof(OTF_FILE_HEADER)); POTF_TABLE_HEADER CurrentTable = NULL; for (USHORT t = 0; t < htons(Hdr->numTables); t++) { ULONG Offset = htonl(Table->offset), Length = htonl(Table->length); if (i >= Offset && i < Offset + Length) { // fix OTF/TTF table checksum and length ULONG Sum = OTF_CalcTableChecksum((ULONG *)((PUCHAR)pBigData + Offset), Length); Table->checkSum = htonl(Sum); Table->length = htonl(Length); CurrentTable = Table; break; } Table += 1; } if (CurrentTable) { Table = (POTF_TABLE_HEADER)((PUCHAR)pBigData + sizeof(OTF_FILE_HEADER)); for (USHORT t = 0; t < htons(Hdr->numTables); t++) { ULONG Offset = htonl(Table->offset), Length = htonl(Table->length); if (Offset > htonl(CurrentTable->offset)) { // fix offsets of the other tables Table->offset = htonl(Offset + BIG_BUFFER_LENGTH); } Table += 1; } } } if (DumpToFile(m_TmpFontPath, pBigData, m_dwDataSize + BIG_BUFFER_LENGTH)) { FuzzIteration(); m_dwCasesProcessed++; } } if (m_dwCasesProcessed > MAX_CASES_PER_PROCESS) { TCHAR szSelf[MAX_PATH], szCmdLine[MAX_PATH]; GetModuleFileName(GetModuleHandle(NULL), szSelf, MAX_PATH); _stprintf_s( szCmdLine, MAX_PATH, _T("\"%s\" \"%s\" \"%s\" -BLOCK_SIZE 0x%x -BLOCK_RANGE_START 0x%x -BLOCK_RANGE_END 0x%x -BLOCK_RANGE_N 0x%x -FILE_RANGE_START 0x%x --resume Y"), szSelf, m_lpFontName, m_lpFontPath, BLOCK_SIZE, BLOCK_RANGE_START, BLOCK_RANGE_END, BLOCK_RANGE_N, i ); if (m_bNoisy) { _tcscat(szCmdLine, _T(" --noisy Y")); } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); // create a new fuzzer instance if (!CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { MessageBox(0, _T("CreateProcess() fails"), _T("ERROR"), MB_ICONERROR); } ExitProcess(0); } } DbgMsg(__FILE__, __LINE__, "Done; %d cases processed\n", m_dwCasesProcessed); if (pBigData) { M_FREE(pBigData); } if (lpszBigBuff) { M_FREE(lpszBigBuff); } M_FREE(m_pAlignedData); } } M_FREE(m_pData); } else { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Error while reading input file\n"); } end: if (m_hWndEvent) { CloseHandle(m_hWndEvent); } printf("Press any key to quit...\n"); _getch(); return 0; }
enum CScript::SCRIPTRETURN CScript::For(const char* CmdStr, char* retStr) { // 获取变量 int cmdLen = strlen(CmdStr); char* szBeginCmd = GetStringParam(CmdStr, 0); if(!szBeginCmd) return CScript::SR_ERROR; int szCmdLen = strlen(szBeginCmd); szBeginCmd[szCmdLen] = ';'; szBeginCmd[szCmdLen+1] = '\0'; char* szMaxCmd = GetStringParam(CmdStr, 1); if(!szMaxCmd) { M_FREE( szBeginCmd, sizeof(char)*MAX_VAR_LEN ); return CScript::SR_ERROR; } szCmdLen = strlen(szMaxCmd); szMaxCmd[szCmdLen] = ';'; szMaxCmd[szCmdLen+1] = '\0'; char* szCountCmd = GetStringParam(CmdStr, 2); if(!szCountCmd) { M_FREE( szBeginCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( szMaxCmd, sizeof(char)*MAX_VAR_LEN ); return CScript::SR_ERROR; } szCmdLen = strlen(szCountCmd); szCountCmd[szCmdLen] = ';'; szCountCmd[szCmdLen+1] = '\0'; //读取For脚本内容 char* chr = NULL; chr = m_Data; long beginPos = 0; // 子脚本起始位置 long endPos = 0; // 子脚本结束位置 beginPos = m_Point; int forBlockNum = 0; // For函数的内部括号计数 ReadForCmd(beginPos, endPos); // 从当前脚本数据中重新生成循环子脚本数据 char* scriptBuf = (char*)M_ALLOC(sizeof(char)*m_DataLen); //memset(scriptBuf, 0, m_DataLen); memcpy(scriptBuf, &m_Data[beginPos], (endPos-beginPos+1)); scriptBuf[(endPos-beginPos+1)+1] = '\0'; CScript* forScript = BeginForScript(scriptBuf); if(NULL == forScript) { M_FREE( szBeginCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( szMaxCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( szCountCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( scriptBuf, sizeof(char)*m_DataLen ); return CScript::SR_ERROR; } CScript::SCRIPTRETURN retFlag = CScript::SR_END; // 将Count变量值改变 RunLine(szBeginCmd); RunLine(szMaxCmd); #ifdef _RUNSTACKINFO_ char pszStatckInfo[10240]=""; _snprintf(pszStatckInfo,10240,"For(beginStr:%s,endStr:%s) Start",szBeginCmd,szMaxCmd); CMessage::AsyWriteFile(GetGame()->GetStatckFileName(),pszStatckInfo); #endif while(1 == m_Value[0]) { retFlag = CScript::SR_END; //重置当前指针 forScript->ResetDataPos(); //记录进入子脚本 EnterChildScript(CST_FOR,forScript,szCountCmd,szMaxCmd); retFlag = forScript->RunStep(); //只要该脚本不挂起,就记录离开子脚本 if(retFlag != CScript::SR_HANG) LeaveChildScript(forScript); //脚本挂起 if(retFlag == CScript::SR_HANG) { #ifdef _RUNSTACKINFO_ _snprintf(pszStatckInfo,10240,"For(beginStr:%s,endStr:%s) Hang",szBeginCmd,szMaxCmd); CMessage::AsyWriteFile(GetGame()->GetStatckFileName(),pszStatckInfo); #endif SetIsHang(true); SetHangFunc(forScript->GetHangFunc()); M_FREE( scriptBuf, sizeof(char)*m_DataLen ); M_FREE( szBeginCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( szMaxCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( szCountCmd, sizeof(char)*MAX_VAR_LEN ); return retFlag; } else if(retFlag == CScript::SR_FORBREAK || retFlag == CScript::SR_RETURN || retFlag == CScript::SR_ERROR) { if(retFlag == CScript::SR_FORBREAK) retFlag = CScript::SR_END; break; } //在retFlag == CScript::SR_FORCONTINUE或者其他况下,继续执行 RunLine(szCountCmd); RunLine(szMaxCmd); } EndForScript(forScript); #ifdef _RUNSTACKINFO_ _snprintf(pszStatckInfo,10240,"For(beginStr:%s,endStr:%s) End",szBeginCmd,szMaxCmd); CMessage::AsyWriteFile(GetGame()->GetStatckFileName(),pszStatckInfo); #endif M_FREE( scriptBuf, sizeof(char)*m_DataLen ); M_FREE( szBeginCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( szMaxCmd, sizeof(char)*MAX_VAR_LEN ); M_FREE( szCountCmd, sizeof(char)*MAX_VAR_LEN ); return retFlag; }
//-------------------------------------------------------------------------------------- void DbgMsg(char *lpszFile, int Line, char *lpszMsg, ...) { va_list mylist; char *lpszBuff = (char *)M_ALLOC(DBGMSG_BUFF_SIZE); if (lpszBuff == NULL) { return; } char *lpszOutBuff = (char *)M_ALLOC(DBGMSG_BUFF_SIZE); if (lpszOutBuff == NULL) { M_FREE(lpszBuff); return; } va_start(mylist, lpszMsg); vsprintf(lpszBuff, lpszMsg, mylist); va_end(mylist); sprintf(lpszOutBuff, "%s(%d) : %s", GetNameFromFullPath(lpszFile), Line, lpszBuff); #ifdef DBGMSG DbgPrint(lpszOutBuff); #endif #if defined(DBGPIPE) || defined(DBGLOGFILE) if (KeGetCurrentIrql() == PASSIVE_LEVEL) { KeWaitForMutexObject(&DbgMutex, Executive, KernelMode, FALSE, NULL); if (hDbgPipe) { // write debug message into pipe IO_STATUS_BLOCK IoStatusBlock; ULONG Len = (ULONG)strlen(lpszOutBuff) + 1; ZwWriteFile(hDbgPipe, 0, NULL, NULL, &IoStatusBlock, (PVOID)&Len, sizeof(Len), NULL, NULL); ZwWriteFile(hDbgPipe, 0, NULL, NULL, &IoStatusBlock, lpszOutBuff, Len, NULL, NULL); } if (hDbgLogFile) { // write debug message into logfile IO_STATUS_BLOCK IoStatusBlock; ULONG Len = (ULONG)strlen(lpszOutBuff); ZwWriteFile(hDbgLogFile, 0, NULL, NULL, &IoStatusBlock, lpszOutBuff, Len, NULL, NULL); } KeReleaseMutex(&DbgMutex, FALSE); } #endif // DBGPIPE/DBGLOGFILE M_FREE(lpszBuff); M_FREE(lpszOutBuff); }