static int et199_encrypt_excute_flie(void *encrypt, char *file_name, char *inbuf, char *outbuf, char *passwd) { ENCRYPT *encrypt_ins = (ENCRYPT *)encrypt; struct ET_CONTEXT*pContext = (struct ET_CONTEXT*)encrypt_ins->private_data; int dwRet = 0; long unsigned int len = 0; dwRet = ETVerifyPin(&pContext[0], (unsigned char *)passwd, strlen(passwd), ET_USER_PIN); if(dwRet) { if(dwRet == ET_E_KEY_REMOVED || dwRet == ET_E_NO_LIST) { return DEV_REMOVED; } PostError("et199_encrypt_excute_flie ETVerifyPin", dwRet); return VERIFYPASSWD_ERR; } dwRet = ETExecute(&pContext[0], file_name, (unsigned char *)inbuf, strlen(inbuf), (unsigned char *)outbuf, BUF_LEN, &len); if(dwRet) { if(dwRet == ET_E_KEY_REMOVED || dwRet == ET_E_NO_LIST) { return DEV_REMOVED; } PostError("et199_encrypt_excute_flie ETExecute",dwRet); return EXCUTEFILE_ERR; } return len; }
void MessageLog::PostStockError(unsigned int StockNum, const char *ErrorMsg) { if (StockNum <= WCS_LOG_ERR_NULL) { TempBuffer[0] = NULL; if (StockErrors[StockNum].Severity >= WCS_LOG_SEVERITY_ERR) { strcpy(TempBuffer, "ERR:"); } // if else if (StockErrors[StockNum].Severity >= WCS_LOG_SEVERITY_WNG) { strcpy(TempBuffer, "WNG:"); } // if else if (StockErrors[StockNum].Severity >= WCS_LOG_SEVERITY_MSG) { strcpy(TempBuffer, "MSG:"); } // if else if (StockErrors[StockNum].Severity >= WCS_LOG_SEVERITY_DTA) { strcpy(TempBuffer, "DTA:"); } // if strcat(TempBuffer, StockErrors[StockNum].Text); strncat(TempBuffer, ErrorMsg, WCS_LOG_LINE_WIDTH - strlen(TempBuffer) - 5); TempBuffer[WCS_LOG_LINE_WIDTH - 1] = NULL; PostError(StockErrors[StockNum].Severity, TempBuffer); } // if else { PostError(WCS_LOG_SEVERITY_ERR, "Unknown Error."); } // else } // MessageLog::PostStockError
static int et199_encrypt_write_data(void *encrypt, char *src_data, int length, FILE_TYPE type) { ENCRYPT *encrypt_ins = (ENCRYPT *)encrypt; struct ET_CONTEXT*pContext = (struct ET_CONTEXT*)encrypt_ins->private_data; int dwRet = 0; if(length > DATA_FILE_LENGTH) { return WRITE_LEN_LONGER; } dwRet = ETVerifyPin(&pContext[0], (unsigned char *)encrypt_ins->dev_passwd, strlen(encrypt_ins->dev_passwd), ET_DEV_PIN); if(dwRet) { if(dwRet == ET_E_KEY_REMOVED || dwRet == ET_E_NO_LIST) { return DEV_REMOVED; } PostError("ETVerifyPin", dwRet); return VERIFYPASSWD_ERR; } dwRet = ETWriteFile(&pContext[0], file_name[type], 0, (unsigned char *)src_data, length); if(dwRet) { if(dwRet == ET_E_KEY_REMOVED || dwRet == ET_E_NO_LIST) { return DEV_REMOVED; } PostError("ETWriteFile", dwRet); return WRITEFILE_ERR; } return 0; }
void PLH::VEHHook::UnHook() { std::lock_guard<std::mutex> m_Lock(m_TargetMutex); if (m_ThisCtx.m_Type == VEHMethod::INT3_BP) { MemoryProtect Protector(m_ThisCtx.m_Src, 1, PAGE_EXECUTE_READWRITE); *m_ThisCtx.m_Src = m_ThisCtx.m_StorageByte; }else if (m_ThisCtx.m_Type == VEHMethod::HARDWARE_BP) { CONTEXT Ctx; Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; if (!GetThreadContext(GetCurrentThread(), &Ctx)) { PostError(PLH::RuntimeError(RuntimeError::Severity::Critical, "Failed to get context")); return; } Ctx.Dr7 &= ~(1 << (2 * m_ThisCtx.m_StorageByte)); //Still need to call suspend thread if (!SetThreadContext(GetCurrentThread(), &Ctx)) { PostError(PLH::RuntimeError(RuntimeError::Severity::Critical, "Failed to set context")); return; } }else if (m_ThisCtx.m_Type == VEHMethod::GUARD_PAGE) { volatile BYTE GenerateExceptionRead = *m_ThisCtx.m_Src; } m_HookTargets.erase(std::remove(m_HookTargets.begin(), m_HookTargets.end(), m_ThisCtx), m_HookTargets.end()); }
void MessageLog::OpenLogFile(char *LogName) { char *TimeStr /*, *FileBase */; time_t Now; strncpy(LogFileName, LogName, 250); LogFileName[254] = NULL; LogFileEnable = 1; /* for(FileBase = LogName; *FileBase != NULL; FileBase++); while(!(FileBase < LogName)) { if ((*FileBase == '\\') || (*FileBase == '/')) { break; } // if FileBase--; } // while */ time(&Now); TimeStr = ctime(&Now); TimeStr[24] = NULL; sprintf(TempBuffer, "Log File \"%s\" opened on %s.", LogName, TimeStr); PostError(0, TempBuffer); } // MessageLog::OpenLogFile
void MessageLog::CloseLogFile(void) { LogFileEnable = 0; PostError(0, "Log File Closed."); } // MessageLog::CloseLogFile
// Initialize the module, staring a worker thread to load the shared object. virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { nacl_io_init_ppapi( pp_instance(), pp::Module::Get()->get_browser_interface()); // printf( "Constructor thread id '%p'\n", pthread_self()); // printf( "createFS thread id '%p'\n", pthread_self()); umount("/"); int res = mount("", "/", "memfs", 0, ""); // int res = mount("", "/web", "httpfs", 0, ""); if (res) { // std::cout << "unable to mount httpfs file system!" << std::endl; bCreatedFS_ = true; return false; } // std::cout << "mount res: " << res << std::endl; if (pthread_create( &message_thread_, NULL, &LASzipInstance::HandleMessageThread, this)) { PostError("Init", "Unable to initialize thread!", "null"); return false; } InitializeMessageQueue(); return true; }
static DWORD WINAPI CrashReportGenerateThread(LPVOID data) { MINIDUMP_EXCEPTION_INFORMATION *ExceptionInfo=(MINIDUMP_EXCEPTION_INFORMATION *)data; HWND hwnd; int res; if (MiniDumpWriteDumpFn!=NULL) { hwnd=CreateWindowEx(WS_EX_TOPMOST,"STATIC","V programu nastala chyba\r\n\r\nSystem Windows nyni sbira informace o chybe a generuje potrebne soubory.\r\nProsim cekejte, tato operace muze trvat trochu dele...",WS_POPUP| WS_DLGFRAME|WS_VISIBLE|SS_CENTER,0,0,640,80,NULL,NULL,GetModuleHandle(NULL),NULL); UpdateWindow(hwnd); if (GenerateMinidump(ExceptionInfo,MiniDumpWithIndirectlyReferencedMemory,".short.dmp")==false) return 0; // GenerateMinidump(ExceptionInfo,MiniDumpWithDataSegs|MiniDumpWithIndirectlyReferencedMemory,".long.dmp"); GenerateMinidump(ExceptionInfo,MiniDumpWithFullMemory,".full.dmp"); PostError(0); DestroyWindow(hwnd); } else { res=MessageBox(0,"V programu nastala chyba. Bohuzel neni pritomen soubor DbgHelp.dll v adresari hry, " "neni tedy mozne vytvorit zaznam o chybe. Ze stranek http://skeldal.vyletnici.net je mozne" "tento soubor stahnout a tim pomoci autorovi odhalit a opravit tyto zaludne pady.\r\n\r\n" "Chcete prejit na stranky obsahujici posledni verze potrebnych souboru?",0,MB_YESNO|MB_SYSTEMMODAL); if (res==IDYES) ShellExecute(0,0,"http://skeldal.vyletnici.net/main.php?page=download",0,0,SW_NORMAL); } return 0; }
bool PLH::VEHHook::Hook() { //Lock the TargetMutex for thread safe vector operations std::lock_guard<std::mutex> m_Lock(m_TargetMutex); if (m_ThisCtx.m_Type == VEHMethod::INT3_BP) { //Write INT3 BreakPoint MemoryProtect Protector(m_ThisCtx.m_Src, 1, PAGE_EXECUTE_READWRITE); m_ThisCtx.m_OriginalByte = *m_ThisCtx.m_Src; *m_ThisCtx.m_Src = 0xCC; m_HookTargets.push_back(m_ThisCtx); }else if (m_ThisCtx.m_Type == VEHMethod::GUARD_PAGE){ //Read current page protection MEMORY_BASIC_INFORMATION mbi; VirtualQuery(m_ThisCtx.m_Src, &mbi, sizeof(mbi)); //can't use Page Guards with NO_ACCESS flag if (mbi.Protect & PAGE_NOACCESS) { PostError(RuntimeError(RuntimeError::Severity::UnRecoverable, "PolyHook VEH: Cannot hook page with NOACCESS Flag")); return false; } if (AreInSamePage((BYTE*)&PLH::VEHHook::VEHHandler, m_ThisCtx.m_Src)) { PostError(RuntimeError(RuntimeError::Severity::UnRecoverable, "PolyHook VEH: Cannot hook page on same page as the VEH")); return false; } //!!!!COMPILER SPECIFIC HACK HERE!!!!! bool(PLH::VEHHook::* pHookFunc)(void) = &PLH::VEHHook::Hook; if (AreInSamePage((BYTE*&)pHookFunc, m_ThisCtx.m_Src)) { PostError(RuntimeError(RuntimeError::Severity::UnRecoverable, "PolyHook VEH: Cannot hook page on same page as the hooking function")); return false; } m_HookTargets.push_back(m_ThisCtx); //Write Page Guard protection DWORD OldProtection; VirtualProtect(m_ThisCtx.m_Src, 1 ,PAGE_EXECUTE_READWRITE | PAGE_GUARD, &OldProtection); } return true; }
static int et199_encrypt_init(void *encrypt) { int dwCount = 0; int dwRet = 0; ENCRYPT *encrypt_ins = encrypt; struct ET_CONTEXT *pContext = (struct ET_CONTEXT *)encrypt_ins->private_data; dwRet = ETEnum(0, &dwCount); if(dwRet != ET_E_INSUFFICIENT_BUFFER && dwRet) { PostError("ETEnum 1", dwRet); return PROBE_ERR; } if(dwCount > PCONTEXT_COUNT) { return MORE_DEV; } memset(pContext, 0, sizeof(struct ET_CONTEXT)*dwCount); dwRet = ETEnum(pContext, &dwCount); if(dwRet) { PostError("ETEnum 2", dwRet); return PROBE_ERR; } //Open ET199 dwRet = ETOpen(&pContext[0]); if(dwRet) { PostError("ETOpen", dwRet); return OPENDEV_ERR; } dwRet = et199_encrypt_verfiy_serial_num(encrypt_ins); if(dwRet != 0) { return dwRet; } return SUCCESS; }
static int et199_encrypt_creat_flie(void *encrypt, char *file_name, int size, char *passwd, int file_type) { ENCRYPT *encrypt_ins = (ENCRYPT *)encrypt; struct ET_CONTEXT *pContext = (struct ET_CONTEXT *)encrypt_ins->private_data; int dwRet = 0; dwRet = ETVerifyPin(&pContext[0], (unsigned char *)passwd, strlen(passwd), ET_DEV_PIN); if(dwRet) { PostError("ETVerifyPin",dwRet); return VERIFYPASSWD_ERR; } dwRet = ETCreateFile(&pContext[0], file_name, size, file_type); if(dwRet) { PostError("ETCreateFile", dwRet); return CREATEFILE_ERR; } return SUCCESS; }
bool PLH::X86Detour::Hook() { DWORD OldProtection; m_hkLength = CalculateLength(m_hkSrc, 5); m_OriginalLength = m_hkLength; if (m_hkLength == 0) { XTrace("Function to small to hook\n"); return false; } m_Trampoline = new BYTE[m_hkLength + 30]; //Allocate Space for original plus extra to jump back and for jmp table VirtualProtect(m_Trampoline, m_hkLength + 5, PAGE_EXECUTE_READWRITE, &OldProtection); //Allow Execution m_NeedFree = true; memcpy(m_OriginalCode, m_hkSrc, m_hkLength); memcpy(m_Trampoline, m_hkSrc, m_hkLength); //Copy original into allocated space RelocateASM(m_Trampoline, m_hkLength, (DWORD)m_hkSrc, (DWORD)m_Trampoline); WriteRelativeJMP((DWORD)&m_Trampoline[m_hkLength], (DWORD)m_hkSrc + m_hkLength); //JMP back to original code //Change protection to allow write on original function MemoryProtect Protector(m_hkSrc, m_hkLength, PAGE_EXECUTE_READWRITE); //Encode Jump from Hooked Function to the Destination function WriteRelativeJMP((DWORD)m_hkSrc, (DWORD)m_hkDest); //Write nops over bytes of overwritten instructions for (int i = 5; i < m_OriginalLength; i++) m_hkSrc[i] = 0x90; FlushSrcInsCache(); //Revert to old protection on original function VirtualProtect(m_hkSrc, m_hkLength, OldProtection, &OldProtection); PostError(RuntimeError(RuntimeError::Severity::Warning, "PolyHook x86Detour: Some opcodes may not be relocated properly")); return true; /*Original -JMP Destination -NOP (extends to length of overwritten opcode) -Rest of function Destination -Do your shit -Return Trampoline (goes to trampoline) Trampoline -Execute Overwritten Opcodes -Patch original relative jmps to point to jump table (JE Jumptable entry 1) -JMP to rest of function (in original) -*BEGIN JUMPTABLE* -1)JMP to location of relative jmp one -2)...continue pattern for all relative jmps */ }
static int et199_encrypt_control(void *encrypt, int cmd, void *para) { ENCRYPT *encrypt_ins = (ENCRYPT *)encrypt; struct ET_CONTEXT*pContext = (struct ET_CONTEXT*)encrypt_ins->private_data; int dwRet = 0; dwRet = ETControl(&pContext[0], cmd, (unsigned char *)para, sizeof(para), NULL, 0, NULL); if(dwRet) { PostError("ETControl ",dwRet); return CONTROL_ERR; } return SUCCESS; }
PLH::VEHHook::VEHHook() { //Get size of pages SYSTEM_INFO si; GetSystemInfo(&si); m_PageSize = si.dwPageSize; void* pVEH = AddVectoredExceptionHandler(1, &PLH::VEHHook::VEHHandler); if (pVEH == nullptr) { PostError(RuntimeError(RuntimeError::Severity::UnRecoverable, "PolyHook VEH: Failed to create top level handler")); } }
void MessageLog::ForceLogOpen(void) { if (LoggedLines) { OpenLogWin(); } // if else { PostError(255, "Log Window Opened."); } // else } // MessageLog::ForceLogOpen
/*----------------------------------------------*/ bool PLH::IATHook::Hook() { PIMAGE_THUNK_DATA Thunk; if (!FindIATFunc(m_hkLibraryName.c_str(), m_hkSrcFunc.c_str(), &Thunk, m_hkModuleName.c_str())) { PostError(RuntimeError(RuntimeError::Severity::UnRecoverable, "PolyHook IATHook: Failed to find import")); return false; } MemoryProtect Protector(Thunk, sizeof(ULONG_PTR), PAGE_EXECUTE_READWRITE); m_pIATFuncOrig = (void*)Thunk->u1.Function; Thunk->u1.Function = (ULONG_PTR)m_hkDest; return true; }
static int et199_encrypt_get_serial_num(void *encrypt, unsigned char *serial_num) { unsigned long count = 0; int dwRet = 0; ENCRYPT *encrypt_ins = encrypt; struct ET_CONTEXT *pContext = (struct ET_CONTEXT *)encrypt_ins->private_data; dwRet = ETControl(&pContext[0], ET_GET_SERIAL_NUMBER, NULL, 0, (unsigned char *)serial_num, WDD_HARDWARE_ID_LEN, &count); if(dwRet) { PostError("et199_encrypt_get_serial_num", dwRet); printf("dwtret = %x\n", dwRet); return GET_SERIAL_ERR; } return SUCCESS; }
/****************************************************************************** * * * BOOL cmdHelp(char *args, int subClass) * * * ******************************************************************************* * * Display Help info * ******************************************************************************/ BOOL cmdHelp(char *args, int subClass) { int nLine = 1; int i; if( *args ) { // Help on a specific command // Search for the specified command in the command array i = 0; while( Cmd[i].sCmd ) { if( !strnicmp(args, Cmd[i].sCmd, strlen(args)) ) break; i++; } // Did we find it? if( Cmd[i].sCmd ) { dprinth(nLine++, "%s", sHelp[Cmd[i].iHelp] + 9); dprinth(nLine++, "%s", Cmd[i].sSyntax); dprinth(nLine++, "%s", Cmd[i].sExample); } else { // Nope - user typed invalid command PostError(ERR_COMMAND, 0); } } else { // General help - list all commands and their short descriptions i = 0; do { if(dprinth(nLine++, "%s", sHelp[i++])==FALSE) break; } while( sHelp[i] != NULL ); } return(TRUE); }
/****************************************************************************** * * * int GetOnOff(char *args) * * * ******************************************************************************* * * Parser helper: Returns [ON | OFF] state + extra * ON = 1 * OFF = 2 * <none> = 3 * KERNEL = 4 * For any other token, it prints the syntax error and returns 0. * ******************************************************************************/ int GetOnOff(char *args) { int len; while( *args==' ') args++; len = strlen(args); if( len==0 ) return( 3 ); // No token - end of argument if( len==2 && !strnicmp(args, "on", 2) ) return( 1 ); // ON if( len==3 && !strnicmp(args, "off", 3) ) return( 2 ); // OFF if( len==6 && !strnicmp(args, "kernel", 6) ) return( 4 ); // KERNEL PostError(ERR_SYNTAX, 0); return( 0 ); }
//***************************************************************************** // Set the pointers to consecutive areas of a large buffer. //***************************************************************************** HRESULT CMiniMd::SetTablePointers( BYTE *pBase, ULONG cbData) { ULONG ulOffset = 0; // Offset so far in the table. int i; // Loop control. for (i=0; i<TBL_COUNT; ++i) { METADATATRACKER_ONLY(MetaDataTracker::NoteSection(i, pBase + ulOffset, m_TableDefs[i].m_cbRec * m_Schema.m_cRecs[i], m_TableDefs[i].m_cbRec)); // Table pointer points before start of data. Allows using RID as // an index, without adjustment. m_pTable[i] = pBase + ulOffset - m_TableDefs[i].m_cbRec; ulOffset += m_TableDefs[i].m_cbRec * m_Schema.m_cRecs[i]; } if (ulOffset > cbData) return PostError(CLDB_E_FILE_CORRUPT); return S_OK; } // HRESULT CMiniMd::SetTablePointers()
UINT ValidateUpdate(HINSTANCE hInst, CDownloadUI *piDownloadUI, LPCSTR szAppTitle, __in LPSTR szUpdatePath, LPCSTR szModuleFile, ULONG ulMinVer) { UINT uiRet = ERROR_SUCCESS; char szShortPath[MAX_PATH] = {0}; // ensure Update is right version for Windows Installer upgrade if (!IsUpdateRequiredVersion(szUpdatePath, ulMinVer)) { // Update won't get us the right upgrade PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_INCORRECT_UPDATE, szUpdatePath); return ERROR_INVALID_PARAMETER; } // upgrade msi uiRet = ExecuteUpgradeMsi(szUpdatePath); switch (uiRet) { case ERROR_SUCCESS: case ERROR_SUCCESS_REBOOT_REQUIRED: { // nothing required at this time break; } case ERROR_FILE_NOT_FOUND: { // Update executable not found PostFormattedError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_NOUPDATE, szUpdatePath); break; } default: // failure { // report error PostError(hInst, piDownloadUI->GetCurrentWindow(), szAppTitle, IDS_FAILED_TO_UPGRADE_MSI); break; } } return uiRet; }
/****************************************************************************** * * * BOOL Unsupported(char *args, int subClass) * * * ******************************************************************************* * * Unsupported command stub * ******************************************************************************/ BOOL Unsupported(char *args, int subClass) { PostError(ERR_NOT_IMPLEMENTED, 0); return( TRUE ); }
/****************************************************************************** * * * BOOL CommandExecute( char *pOrigCmd ) * * * ******************************************************************************* * * Executes commands stored in a string. If the command contains a macro, * this function is called recursively. * * We also exit if there was an error evaluating a command. * * Where: * pOrigCmd is the string with commands. Multiple commands may be separated * with ';' * * Returns: * FALSE if the command reuqested debugger to continue running * the debugee program (such are commands 'g' or 't') * TRUE if suggested staying in the debugger * ******************************************************************************/ BOOL CommandExecute( char *pOrigCmd ) { static int nDeep = 0; // Recursion depth count char Command[MAX_STRING]; // Command buffer on the stack char *pCmd = Command; // Pointer to a local buffer char *pCmdNext, cDelimiter; char *pMacro; // Pointer to a macro string (expanded) BOOL fInString, fRet = TRUE; int i; nDeep++; // Inside the function, recursion count // Copy given command(s) into a local buffer so we can recurse strcpy(pCmd, pOrigCmd); do { // Find the first non-space, non-delimiter character of the current command while( (*pCmd==' ' || *pCmd==';') && (*pCmd!=0) ) pCmd++; // Look for the ";" delimiter, ignore it within a string pCmdNext = pCmd; fInString = FALSE; while( *pCmdNext!=0 && (*pCmdNext!=';' || fInString) ) { if( *pCmdNext=='"' ) fInString = !fInString; pCmdNext++; } // If the command is empty, return if( *pCmd==0 ) break; // Got the first character.. Search all known command keywords from // back to front to find a match for( i=iLast; i>=0; i--) { if( !strnicmp(pCmd, Cmd[i].sCmd, Cmd[i].nLen) && !isalnum(pCmd[Cmd[i].nLen])) break; } // Separate current string from the next one cDelimiter = *pCmdNext; *pCmdNext = 0; if( i>= 0 ) { // Find the first non-space character to assign it as a pointer to the first argument pCmd += Cmd[i].nLen; while( *pCmd==' ' ) pCmd++; // Call the command function handler fRet = (Cmd[i].pfnCommand)( pCmd, Cmd[i].subClass ); } else { // Command was not found. Search all defined macros. pMacro = MacroExpand(pCmd); if( pMacro != NULL ) { // Recursively submit expanded macro for execution // Keep the recursion count so we can terminate if too deep if( nDeep <= MAX_MACRO_RECURSE ) fRet = CommandExecute(pMacro); else fRet = TRUE; } else { // The last thing we search the extended commands (DOT-commands) // Only if the first character is a DOT, though if( *pCmd=='.' ) { return( DispatchExtCommand(pCmd+1) ); } else { PostError(ERR_COMMAND, 0); return( TRUE ); } } } // Restore the delimiter character *pCmdNext = cDelimiter; pCmd = pCmdNext; } while( (*pCmd != 0) && fRet ); nDeep--; // Leaving the function, recursion count return( fRet ); }
char *WriteSeq( char *outSpec, /* Output sequence spec */ SeqEntry *seq, /* Seq Entry data structure */ int format) /* Output format */ { #define SIZE 255 /* String size */ char line[SIZE], header[SIZE], code[SIZE], testCode[SIZE]; char outFName[SIZE]; char *cPos, *pStrand; int lineSize, blockSize; int count, nOut; Boolean twoFiles; Boolean doText; char errMsg[SIZE]; static char outFileName[SIZE]; /* Static because it's the return value */ FILE *outFile, *inFile; /* ** Process available text for formats which allow freely formated text. */ switch ( format ) { case PIR: case GCG: doText = (seq->text != NULL); break; default: doText = 0; break; } /* ** Set LineSize and BlockSize for variou formats */ switch ( seq->spec->format ) { case GCG: lineSize = 50; blockSize= 10; break; case PIR: case IBI: lineSize = 60; blockSize = 10; break; case IG: case STRIDER: default: lineSize = blockSize= 80; } /* ** Extract the the code from OutSpec for multi-entry files. If OutSpec just ** has a filename then strip off the extension and use the filename as the code. ** Filenames are to the right of the equals. ** N.B. does not yet support pathnames. ** ** Outspec will look like either: ** ** code=filename.ext OR filename.ext */ if ( (cPos = strchr(outSpec,';')) ) *cPos = '\0'; /* Remove version */ strcpy(code,outSpec); if ( (cPos = strchr(code,'=')) ) *cPos = '\0'; /* code=filename.ext */ if ( (cPos = strchr(code,'.')) ) *cPos = '\0'; /* filename.ext */ StrToUpper(code); strcpy(outFName,outSpec); if ( (cPos = strchr(outFName,'=')) ) strcpy(outFName, ++cPos); /* ** Are we dealing with a new or old sequence file? Test for an existing ** file set "twoFiles" flag accordingly. */ if ( (inFile = fopen(outFName, "r")) ) { if ( !(outFile = fopen(outFName, "w")) ) goto Error; twoFiles = 1; } else { if ( !(outFile = fopen(outFName, "w")) ) goto Error; twoFiles = 0; } /* ** Do what needs to be done to prepare the file for writing or over-writing ** the new sequence data. ** ** PIR - create header, read into filename until we find the entry to ** replace or reach EOF. Save existing text if there is no new text. ** ** IG - Save any lines beginning with ";" these are comment characters. ** Write out codeword. Generate circular/linear flag. ** ** STADEN - Translate symbols from IUPAC to STADEN, append end of sequence ** character, "@". ** ** GCG - Save all text at the top of the file up to but not including the ** line with ".." in it, unless we have new text. Convert "-"'s to ** "."'s. Recalculate CheckSum. Write a new GCG descriptor line. ** ** IBI - Rewrite the LOCUS line and ORIGIN line. ** ** STRIDER- Write out strider header line and sequnce title. ** ** RAWSEQ - Do nothing. */ switch ( format ) { case PIR: strcpy(header, ">"); switch (seq->type ) { case PROTEIN: strcat(header,"P1;"); break; case FRAGMENT: strcat(header,"F1;"); break; case DNA: seq->circular ? strcat(header,"DC;"):strcat(header,"DL;") ; break; case RNA: seq->circular ? strcat(header,"RC;"):strcat(header,"RL;") ; break; case RRNA: strcat(header,"N1;"); break; case TRNA: strcat(header,"N3;"); break; default: strcat(header,"XX;"); break; } strcat(header, code); /* ** Read in/out until the beginning of entry to be overwritten ** or End of File. */ if ( twoFiles ) { testCode[0] = '\0'; while ( fgets(line, 255, inFile) ) { if( line[0] == '>') { strcpy(testCode, &line[4]); if ( (cPos = strchr(testCode, '\n')) ) *cPos = '\0'; StrToUpper(StrCollapse(testCode)); if( strcmp(testCode,code) == 0 ) break; } fputs(line,outFile); } } /* ** Write out the header and title lines. */ fprintf(outFile,"%s\n", header); fprintf(outFile,"%s\n", seq->title); break; /****************************************************************/ case IG: /* ** For IG format save any lines beginning with ";" these ** are comment characters */ if ( twoFiles && !doText ) { while ( fgets(line, 255, inFile) ) { if ( line[0] != ';' ) break; fputs(line,outFile); } } else if ( doText ) { if ( seq->text ) fputs(seq->text,outFile); } else fprintf(outFile, "; %s\n; %s\n", seq->title,seq->desc); fprintf(outFile, "%s\n", code); break; /****************************************************************/ case STADEN: if (seq->type >= DNA ) { StrChange(seq->mem,'M','5'); StrChange(seq->mem,'K','6'); StrChange(seq->mem,'W','7'); StrChange(seq->mem,'S','8'); StrChange(seq->mem,'m','5'); StrChange(seq->mem,'k','6'); StrChange(seq->mem,'w','7'); StrChange(seq->mem,'s','8'); } break; /****************************************************************/ case GCG: if ( twoFiles && !doText ) { while ( fgets(line, 255, inFile) ) { if ( StrIndex("..",line) ) break; fputs(line,outFile); } } else if ( doText ) { if ( seq->text ) fputs(seq->text,outFile); } else fprintf(outFile, " %s\n %s\n\n", seq->title,seq->desc); StrChange(seq->mem,'-','.'); seq->checkSum = CheckSum(seq->mem); fprintf(outFile, " %s Length: %ld %s Check: %d ..\n", outFName, seq->length, GetTime(3), seq->checkSum); fprintf(outFile," 1 "); break; /****************************************************************/ case IBI: fprintf(outFile, "LOCUS %s %ld BP UPDATED %s\n", code, seq->length, GetTime(0)); if ( twoFiles && !doText ) { while ( fgets(line, 255, inFile) ) { if ( StrIndex("LOCUS",line) ) continue; if ( StrIndex("ORIGIN",line) ) break; fputs(line,outFile); } } else if ( doText && seq->text ) { if ( (cPos = StrIndex("LOCUS ",seq->text)) ) strcpy(seq->text,strchr(cPos,'\n')); if ( (cPos = StrIndex("\nORIGIN",seq->text)) ) *cPos = '\0'; fputs(seq->text,outFile); } fprintf(outFile, "ORIGIN %s\n", seq->title); fprintf(outFile," 1 "); break; /****************************************************************/ case STRIDER: fprintf(outFile,"; ### from DNA Strider %s\n",GetTime(3)); fprintf(outFile,"; %s sequence %s length %ld", DecodeType(seq->type),seq->name,seq->length); if ( seq->type <= PROTEIN ) fprintf(outFile," a.a. complete sequence\n; %s\n",seq->title); else fprintf(outFile," n.a. complete sequence\n; %s\n",seq->title); break; /****************************************************************/ case RAWSEQ: default: break; } /* ** Write the sequence in Block/Line size. "NOut" counts the number ** of symbols written in each line. Support GCG and IBI line numbering ** schemes. */ nOut = 0; count = 1; pStrand = seq->mem; while( *pStrand ) { fprintf(outFile, "%c", *pStrand); nOut++; count++; if ( nOut == lineSize ) { switch ( format ) { case IBI: case GCG: fprintf(outFile,"\n%9d ",count); break; default: fprintf(outFile, "\n"); } nOut=0; } else if ( nOut%blockSize == 0 ) fprintf(outFile, " "); pStrand++; } /* ** Depending on the format we have some finishing up to do. ** ** PIR - Add the End of sequence character. Read past the old sequence ** form the original file. If "DoText" is true, write out the new ** text comments, skip over the comments in the old file, if any. ** Finally, copy the balance of the old file into the new file. ** ** IBI - Add sequence terminator "//" ** ** IG - Append linear/circular flag at end of sequence. ** ** STRIDER - Add sequence terminator "//" ** ** STADEN - Add end of sequence character. Convert sequence symbols back ** to IUPAC. ** ** GCG - Convert "."'s back to "-"'s. Recalc CheckSum. */ switch ( format ) { case PIR: fprintf(outFile,"*\n"); /* Skip over sequence in the old file */ if ( twoFiles ) while ( fgets(line, 255, inFile) ) if( strchr(line,'*' ) ) break; /* Skip over old comments, if any. */ if ( doText ) { if ( seq->text ) fputs(seq->text,outFile); if ( twoFiles ) while ( fgets(line, 255, inFile) ) if( *line == '>' ) { fputs(line,outFile); break; } } /* Copy the remainder of the file */ if ( twoFiles ) { while ( fgets(line, 255, inFile) ) fputs(line, outFile); } break; /****************************************************************/ case IBI: fprintf(outFile,"\n//"); break; /****************************************************************/ case IG: fprintf(outFile,"%c",seq->circular ? '2' : '1'); break; /****************************************************************/ case STRIDER: fprintf(outFile,"\n//"); break; /****************************************************************/ case STADEN: fprintf(outFile,"@"); if (seq->type >= DNA ) { StrChange(seq->mem,'5','M'); StrChange(seq->mem,'6','K'); StrChange(seq->mem,'7','W'); StrChange(seq->mem,'8','S'); } break; /****************************************************************/ case GCG: StrChange(seq->mem,'.','-'); seq->checkSum = CheckSum(seq->mem); break; } /* fgetname(outFile, outFileName); NO IDEA PUT strcopy to compile il*/ strcpy(outFileName,outFName); fclose(outFile); if ( twoFiles ) fclose(inFile); return(outFileName); /* ** The output file could not be created. Set error message and return ** NULL */ Error: sprintf(errMsg, "Output file \"%s\" could not be created.", outFName); PostError(2,errMsg); return(NULL); } /* End of WriteSeq */
//######################################################################## // Loads all bitmap buttons //######################################################################## void LoadButtonBitmap(void) { IMAGEPATH *img = (IMAGEPATH*)GlobalAlloc(GMEM_FIXED, sizeof(IMAGEPATH)); if(img == NULL) PostError(TRUE, "Failed to allocate memory."); lstrcpyA(img->szCancelBmp, SKINFOLDER); lstrcpyA(img->szCancelHoverBmp, SKINFOLDER); lstrcpyA(img->szCloseBmp, SKINFOLDER); lstrcpyA(img->szCloseHoverBmp, SKINFOLDER); lstrcpyA(img->szMinimizeBmp, SKINFOLDER); lstrcpyA(img->szMinimizeHoverBmp, SKINFOLDER); lstrcpyA(img->szRegisterBmp, SKINFOLDER); lstrcpyA(img->szRegisterHoverBmp, SKINFOLDER); lstrcpyA(img->szStartgameBmp, SKINFOLDER); lstrcpyA(img->szStartgameHoverBmp, SKINFOLDER); lstrcatA(img->szCancelBmp, "\\cancel.bmp"); lstrcatA(img->szCancelHoverBmp, "\\cancel_hover.bmp"); lstrcatA(img->szCloseBmp, "\\close.bmp"); lstrcatA(img->szCloseHoverBmp, "\\close_hover.bmp"); lstrcatA(img->szMinimizeBmp, "\\minimize.bmp"); lstrcatA(img->szMinimizeHoverBmp, "\\minimize_hover.bmp"); lstrcatA(img->szRegisterBmp, "\\register.bmp"); lstrcatA(img->szRegisterHoverBmp, "\\register_hover.bmp"); lstrcatA(img->szStartgameBmp, "\\startgame.bmp"); lstrcatA(img->szStartgameHoverBmp, "\\startgame_hover.bmp"); //------------------------ // MINIMIZE BUTTON //------------------------ hbmMinimize = (HBITMAP)LoadImage(NULL, img->szMinimizeBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmMinimize) { PostError(TRUE, "Failed to load minimize.bmp."); } hbmMinimize_hover = (HBITMAP)LoadImage(NULL, img->szMinimizeHoverBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmMinimize_hover) { PostError(TRUE, "Failed to load minimize_hover.bmp."); } hbmClose = (HBITMAP)LoadImage(NULL, img->szCloseBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmClose) { PostError(TRUE, "Failed to load close.bmp."); } hbmClose_hover = (HBITMAP)LoadImage(NULL, img->szCloseHoverBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmMinimize_hover) { PostError(TRUE, "Failed to load close_hover.bmp."); } hbmStartGame = (HBITMAP)LoadImage(NULL, img->szStartgameBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmStartGame) { PostError(TRUE, "Failed to load startgame.bmp."); } hbmStartGame_hover = (HBITMAP)LoadImage(NULL, img->szStartgameHoverBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmStartGame_hover) { PostError(TRUE, "Failed to load startgame_hover.bmp."); } hbmRegister = (HBITMAP)LoadImage(NULL, img->szRegisterBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmRegister) { PostError(TRUE, "Failed to load register.bmp."); } hbmRegister_hover = (HBITMAP)LoadImage(NULL, img->szRegisterHoverBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmRegister_hover) { PostError(TRUE, "Failed to load register_hover.bmp."); } hbmCancel = (HBITMAP)LoadImage(NULL, img->szCancelBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmCancel) { PostError(TRUE, "Failed to load cancel.bmp."); } hbmCancel_hover = (HBITMAP)LoadImage(NULL, img->szCancelHoverBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(!hbmCancel_hover) { PostError(TRUE, "Failed to load cancel_hover.bmp."); } }
/// SimpleDPX::BuildScanPattern // Build the scan pattern for the given element and element description // Returns true for YUV scans. bool SimpleDPX::BuildScanPattern(struct ImageElement *el) { struct ScanElement **slp = &(el->m_pScanPattern); bool yuv = false; UBYTE i; switch(el->m_ucDescriptor) { case 0: case 1: case 2: case 3: case 6: case 4: case 8: // Depth image. Ok, encode this as alpha for the time being. // This is alpha only // These are single-component elements. if (el->m_ucDescriptor == 4 || el->m_ucDescriptor == 8) { el->m_ucAlphaDepth = 1; } else { el->m_ucDepth = 1; } // new ScanElement(slp,0); break; case 7: // This is CbCr, alternating. Is this also subsampled in Y direction? el->m_ucDepth = 2; el->m_ucSubX = 2; el->m_ucSubY = 2; // I hope so... yuv = true; // // Create two scan elements. The first scans Cb, the second Cr. new ScanElement(slp,0); new ScanElement(slp,1); case 9: // "Composite video". Largely underspecified. No idea what the samples are here. yuv = true; PostError("found composite video element in DPX file %s. " "DPX specifications are unsufficient for implementation",m_pcFileName); break; case 50: // This is BGR (not RGB) el->m_ucDepth = 3; // Create three scan elements in the order B,G,R. new ScanElement(slp,2); new ScanElement(slp,1); new ScanElement(slp,0); break; case 51: // This is BGRA (not RGBA) el->m_ucDepth = 3; el->m_ucAlphaDepth = 1; // Create three scan elements in the order B,G,R,A. new ScanElement(slp,2); new ScanElement(slp,1); new ScanElement(slp,0); new ScanElement(slp,MAX_UWORD); break; case 52: // This is ARGB el->m_ucDepth = 3; el->m_ucAlphaDepth = 1; // Create three scan elements in the order A,R,G,B new ScanElement(slp,MAX_UWORD); new ScanElement(slp,0); new ScanElement(slp,1); new ScanElement(slp,2); break; case 100: // This is V210, CbYCrY repeated. el->m_ucDepth = 3; el->m_ucSubX = 2; yuv = true; // Create three scan elements in the order Cb,Y,Cr,Y new ScanElement(slp,1); new ScanElement(slp,0); new ScanElement(slp,2); new ScanElement(slp,0); break; case 101: // This is CbYACrYA el->m_ucDepth = 3; el->m_ucAlphaDepth = 1; el->m_ucSubX = 2; yuv = true; // Create scan elements in the order Cb,Y,A,Cr,Y,A new ScanElement(slp,1); new ScanElement(slp,0); new ScanElement(slp,MAX_UWORD); new ScanElement(slp,2); new ScanElement(slp,0); new ScanElement(slp,MAX_UWORD); break; case 102: // This is CbYCr repeated, non-subsampled. el->m_ucDepth = 3; yuv = true; // Create scan elements in the order Cb,Y,Cr new ScanElement(slp,1); new ScanElement(slp,0); new ScanElement(slp,2); break; case 103: // This is CbYCrA repeated, non-subsampled. el->m_ucDepth = 3; el->m_ucAlphaDepth = 1; yuv = true; new ScanElement(slp,1); new ScanElement(slp,0); new ScanElement(slp,2); new ScanElement(slp,MAX_UWORD); break; case 150: case 151: case 152: case 153: case 154: case 155: case 156: // This is a generic n-element image, with n = 2..8. el->m_ucDepth = el->m_ucDescriptor - 150 + 2; for(i = 0;i < el->m_ucDepth;i++) { new ScanElement(slp,i); } break; default: PostError("found unspecified DPX element descriptor in file %s",m_pcFileName); break; } return yuv; }
/// SimpleDPX::ParseHeader // Parse the file header of a DPX file void SimpleDPX::ParseHeader(FILE *file,struct ImgSpecs &specs) { ULONG hdr; char version[9]; ULONG encryption; UWORD orientation; UWORD depth,alpha; ULONG width,height; UWORD i; struct ComponentLayout *cl; m_bLittleEndian = false; hdr = GetLong(file); if (hdr == MakeID('S','D','P','X')) { // This is big-endian. m_bLittleEndian = false; } else if (hdr == MakeID('X','P','D','S')) { m_bLittleEndian = true; } else { PostError("input file %s is not a valid DPX file",m_pcFileName); } m_ulDataOffset = GetLong(file); version[8] = 0; GetString(file,version,8); if (strcmp(version,"V1.0") && strcmp(version,"V2.0")) PostError("unsupported DPX version detected, only V1.0 and V2.0 are supported"); SkipBytes(file,8); // file size and ditto key are not really needed. // // Read sizes of data structures. m_ulGenericSize = GetLong(file); m_ulIndustrySize = GetLong(file); m_ulUserSize = GetLong(file); // // Skip over the bytes we do not care about. SkipBytes(file,100+24+100+200+200); // // Read the encyrption key. encryption = GetLong(file); if (encryption != ULONG(~0UL)) fprintf(stderr,"Warning! - DPX file %s signals encryption, output may be wrong.\n",m_pcFileName); // // Skip over the rest of the header. not needed. SkipBytes(file,104); // // Read the image orientation orientation = GetWord(file); if (orientation >= 8) PostError("unknown orientation specified in DPX file %s, must be between 0 and 7",m_pcFileName); m_bFlipX = (orientation & 1)?true:false; m_bFlipY = (orientation & 2)?true:false; m_bFlipXY = (orientation & 4)?true:false; m_usElements = GetWord(file); if (m_usElements == 0 || m_usElements > 8) PostError("number of image elements must be between 1 and 8 in DPX file %s",m_pcFileName); width = GetLong(file); height = GetLong(file); if (m_bFlipXY) { m_ulHeight = width; m_ulWidth = height; } else { m_ulWidth = width; m_ulHeight = height; } specs.ASCII = ImgSpecs::No; specs.Interleaved = (m_usElements == 1)?(ImgSpecs::Yes):(ImgSpecs::No); specs.YUVEncoded = ImgSpecs::No; // changed possibly to Yes later on. specs.Palettized = ImgSpecs::No; specs.LittleEndian = (m_bLittleEndian)?(ImgSpecs::Yes):(ImgSpecs::No); // // Image elements. All eight are always present, though only the first m_usElements contain // valid data. for(i = 0;i < 8;i++) { if (i < m_usElements) { m_Elements[i].m_ulWidth = width; m_Elements[i].m_ulHeight = height; if (ParseElementHeader(file,m_Elements + i)) specs.YUVEncoded = ImgSpecs::Yes; } else { // Skip over elements we do not need SkipBytes(file,4*5 + 1*4 + 2*2 + 4*3 + 32); } } // // The rest is junk we do not need. // // Now compute the depth of the image. depth = 0; alpha = 0; for (i = 0;i < m_usElements;i++) { depth += m_Elements[i].m_ucDepth; alpha += m_Elements[i].m_ucAlphaDepth; } CreateComponents(m_ulWidth,m_ulHeight,depth + alpha); // // Now create the planes and allocate memory. cl = m_pComponent; for(i = 0;i < m_usElements;i++) { struct ImageElement *el = m_Elements + i; struct ScanElement *sl = el->m_pScanPattern; while(sl) { struct ComponentLayout *cll; UBYTE bytesperpixel = (el->m_ucBitDepth + 7) >> 3; UBYTE subx = el->m_ucSubX; UBYTE suby = el->m_ucSubY; UWORD k = sl->m_usTargetChannel; // // If flipXY is set, then X and Y change their role, so flip them now. if (m_bFlipXY) { subx = el->m_ucSubY; suby = el->m_ucSubX; } // // LUMA and alpha is always encoded without subsampling. if (k == 0 || k == 3) { subx = suby = 1; } // // Is this an alpha component or not? if (k == MAX_UWORD) { cll = cl + el->m_ucDepth; k = el->m_ucDepth; } else { cll = cl + k; } cll->m_ucBits = m_Elements[i].m_ucBitDepth; cll->m_bSigned = m_Elements[i].m_bSigned; cll->m_bFloat = m_Elements[i].m_bFloat; cll->m_ucSubX = subx; cll->m_ucSubY = suby; cll->m_ulWidth = (m_ulWidth + subx - 1) / subx; cll->m_ulHeight = (m_ulHeight + suby - 1) / suby; cll->m_ulBytesPerPixel = bytesperpixel; cll->m_ulBytesPerRow = cll->m_ulWidth * bytesperpixel; // Check whether we have already data for this channel. If not, allocate now. // As a channel may appear multiple times in one scan pattern, make sure to // allocate only once. if (el->m_pData[k] == NULL) { el->m_pData[k] = new UBYTE[cll->m_ulWidth * bytesperpixel * cll->m_ulHeight]; cll->m_pPtr = el->m_pData[k]; sl->m_bFirst = true; } sl->m_pData = cll->m_pPtr; sl->m_pComponent = cll; sl = sl->m_pNext; } // Adjust the components. cl += el->m_ucDepth + el->m_ucAlphaDepth; } }
/// SimpleDPX::ParseElementHeader // Parse a single element header from the given file. bool SimpleDPX::ParseElementHeader(FILE *file,struct ImageElement *el) { ULONG sign; UBYTE xfer,color; UWORD packing,encoding; bool yuv = false; // // Read an element. sign = GetLong(file); switch(sign) { case 0: el->m_bSigned = false; break; case 1: el->m_bSigned = true; break; default: PostError("found invalid signedness indicator in DPX file %s, must be either 1 or 0",m_pcFileName); break; } // Next four are luma scaling attributes we do not need to support. SkipBytes(file,4+4+4+4); // el->m_ucDescriptor = GetByte(file); // // Read the transfer characteristics. Not that we do anything about it. xfer = GetByte(file); if (xfer > 12) PostError("found unspecified DPX transfer characteristics in file %s",m_pcFileName); // // Read the colorimetric specification. Nothing we can make use of. color = GetByte(file); if (color > 10) PostError("found invalid colorimetric specification in DPX file %s",m_pcFileName); // el->m_ucBitDepth = GetByte(file); // Get the packing information. 0 is full packing, // 1 is with packing bits at the LSB side, 2 is with packing bits at // the MSB side. packing = GetWord(file); if (packing > 2) PostError("found invalid DPX padding specification in file %s",m_pcFileName); // switch(el->m_ucBitDepth) { case 8: case 16: // These are all integer bit depths DPX allows. No padding, no packing. break; case 1: // 11 bit elements are packed to 32 bit LONGs // No padding bits. el->m_ucPackElements = 32; break; case 10: // 10 bit elements are packed to 32 bit LONGs // Padding is possible. switch(packing) { case 1: el->m_ucLSBPaddingBits = 2; break; case 2: el->m_ucMSBPaddingBits = 2; break; } el->m_ucPackElements = 3; break; case 12: // 12 bit elements are packed to 32 bit LONGs. // Three elements are packed into one 32 bit word. switch(packing) { case 1: el->m_ucLSBPaddingBits = 4; break; case 2: el->m_ucMSBPaddingBits = 4; break; } el->m_ucPackElements = 1; break; case 32: case 64: el->m_bFloat = true; break; default: PostError("found invalid DPX bit depth in file %s",m_pcFileName); break; } // yuv = BuildScanPattern(el); // // Get the encoding information. encoding = GetWord(file); switch(encoding) { case 0: // no encoding. break; case 1: // RLE encoding. el->m_bRLE = true; // No idea what RLE and FLOAT is supposed to mean. How is the run length // encoded? if (el->m_bFloat) PostError("RLE encoding and floating point samples as found in file %s " "are undocumented in the DPX specs and not supported",m_pcFileName); break; default: PostError("found invalid DPX encoding specification in file %s",m_pcFileName); break; } // // Get the offset to the data. el->m_ulOffset = GetLong(file); // // Read end of line/end of frame padding. el->m_ulEndOfLinePadding = GetLong(file); // Read end of frame padding. el->m_ulEndOfFramePadding = GetLong(file); // // Skip the 32 bytes description. SkipBytes(file,32); // return yuv; }
bool PLH::IATHook::FindIATFunc(const char* LibraryName,const char* FuncName, PIMAGE_THUNK_DATA* pFuncThunkOut,const char* Module) { bool UseModuleName = true; if (Module == NULL || Module[0] == '\0') UseModuleName = false; HINSTANCE hInst = GetModuleHandleA(UseModuleName ? Module:NULL); if (!hInst) { PostError(RuntimeError(RuntimeError::Severity::UnRecoverable, "PolyHook IATHook:Failed to find Module")); return false; } ULONG Sz; PIMAGE_IMPORT_DESCRIPTOR pImports = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToDataEx(hInst, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Sz, nullptr); for (int i = 0; pImports[i].Characteristics != 0; i++) { char* _ModuleName = (char*)ResolveRVA(hInst, pImports[i].Name); if (_stricmp(_ModuleName, LibraryName) != 0) continue; //Original holds the API Names PIMAGE_THUNK_DATA pOriginalThunk = (PIMAGE_THUNK_DATA) ResolveRVA(hInst, pImports->OriginalFirstThunk); //FirstThunk is overwritten by loader with API addresses, we change this PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ResolveRVA(hInst, pImports->FirstThunk); if (!pOriginalThunk) { PostError(RuntimeError(RuntimeError::Severity::Critical, "PolyHook IATHook:PE Files without OriginalFirstThunk are unsupported")); return false; } //Table is null terminated, increment both tables for (; pOriginalThunk->u1.Function != NULL; pOriginalThunk++,pThunk++) { if (IMAGE_SNAP_BY_ORDINAL(pOriginalThunk->u1.Ordinal)) { XTrace("Import By Ordinal:[Ordinal:%d]\n",IMAGE_ORDINAL(pOriginalThunk->u1.Ordinal)); continue; } PIMAGE_IMPORT_BY_NAME pImport = (PIMAGE_IMPORT_BY_NAME) ResolveRVA(hInst, pOriginalThunk->u1.AddressOfData); XTrace("Import By Name: [Ordinal:%d] [Name:%s]\n", IMAGE_ORDINAL(pOriginalThunk->u1.Ordinal),pImport->Name); //Check the name of API given by OriginalFirthThunk if (_stricmp(FuncName, pImport->Name) != 0) continue; /*Name matched in OriginalFirstThunk, return FirstThunk so we can changed it's address*/ *pFuncThunkOut = pThunk; return true; } } PostError(RuntimeError(RuntimeError::Severity::UnRecoverable, "PolyHook IATHook:Failed to find import")); return false; }
static Boolean NextIndSpec(SeqSpec *indSpec, SeqSpec *thisSpec) { char *cPos, line[256]; int i; static SeqSpec tempSpec = {NULL,NULL,NULL,NULL,0,0,0,UNDEF}; static char options[5][80], currIndFName[256]; static int depth; static FILE *file[5]; /* ** Is this the same indirect command file or a new one? If so, ** copy the filename to list at the zero level. Open the file and ** see if it exists. Scan it for ".." to see there are any header comments ** if ".." cannot be found start back at the top. Read the first line ** of the file by jumping to the "NextLine" label. This seem a little ** convoluted but remeber that this peice of code get executed once, from ** then on it's a nice little dance between the "NextLine" and "NextSeqSpec" ** labels. Read the comments, it does make sence. */ if ( strcmp(currIndFName, indSpec->file) != 0 ) { depth = 0; if ( indSpec->file) strcpy(currIndFName, indSpec->file); if ( indSpec->options) strcpy(options[depth],indSpec->options); if ( (file[depth] = fopen(&indSpec->file[1], "r")) == NULL ) return(0); while ( fgets(line, 255, file[depth]) ) if ( StrIndex("..", line) ) break; if ( feof(file[depth]) ) rewind(file[depth]); goto NextLine; } /* ** At this point a Spec is either from a User file or a database. */ NextSeqSpec: if ( tempSpec.isUser ) { if ( NextUserSpec(&tempSpec, thisSpec) ) return(1); } else { if ( NextDBSpec(&tempSpec, thisSpec) ) return(1); } /* ** Get a line from the indirect file(s), goto NextSeqSpec until it ** the current spec exhausts, i.e. returns false. At which point you will ** fall through to here in order to read the next line. */ NextLine: while ( depth >= 0 ) { while ( fgets(line, 255, file[depth]) ) { if ( (cPos = strchr(line, ' ')) ) *cPos = '\0'; /* First token */ if ( (cPos = strchr(line, '!')) ) *cPos = '\0'; /* Uncomment */ if ( (cPos = strchr(line, '\n')) )*cPos = '\0'; /* String-ize */ if ( line[0] == '\0' ) continue; /* Blank line */ if ( line[0] == '@' ) { /* Another FOSS*/ if ( depth < 5 ) { depth++; if ( (cPos = strchr(line,'/')) ) { strcpy(options[depth],cPos); *cPos = '\0'; } if ( (file[depth] = fopen(&line[1], "r")) ) { while ( fgets(line, 255, file[depth]) ) if ( StrIndex("..", line) ) break; if ( feof(file[depth]) ) rewind(file[depth]); } else { depth--; } } else { PostError(2,"SeqSpec lists are too deeply nested!!"); } } else { /* A Sequence Spec */ for ( i=depth; i>=0; i-- ) /* Append the options from every*/ strcat(line, options[i]); /* FOSS file which came before*/ MakeSeqSpec(&tempSpec, line); /* Assign the SeqSpec structure */ goto NextSeqSpec; /* Dispatch and run down. */ } } fclose(file[depth]); depth--; } /* ** Fall through to here when all of the Sequence Specification from all ** of the FOSS files are finished. */ currIndFName[0] = '\0'; return(0); }