Ejemplo n.º 1
0
bool SymGetModuleList(std::vector<SYMBOLMODULEINFO>* List)
{
    //
    // Inline lambda enum
    //
    auto EnumModules = [](LPCTSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) -> BOOL
    {
        SYMBOLMODULEINFO curModule;
        curModule.base = (duint)BaseOfDll;

        // Terminate module name if one isn't found
        if(!ModNameFromAddr(curModule.base, curModule.name, true))
            curModule.name[0] = '\0';

        ((std::vector<SYMBOLMODULEINFO>*)UserContext)->push_back(curModule);
        return TRUE;
    };

    // Execute the symbol enumerator (Force cast to STDCALL)
    if(!SafeSymEnumerateModules64(fdProcessInfo->hProcess, EnumModules, List))
    {
        dputs("SymEnumerateModules64 failed!");
        return false;
    }

    return true;
}
Ejemplo n.º 2
0
bool FunctionAdd(uint Start, uint End, bool Manual)
{
    // CHECK: Export/Command function
    if(!DbgIsDebugging())
        return false;

    // Make sure memory is readable
    if(!MemIsValidReadPtr(Start))
        return false;

    // Fail if boundary exceeds module size
    const uint moduleBase = ModBaseFromAddr(Start);

    if(moduleBase != ModBaseFromAddr(End))
        return false;

    // Fail if 'Start' and 'End' are incompatible
    if(Start > End || FunctionOverlaps(Start, End))
        return false;

    FUNCTIONSINFO function;
    ModNameFromAddr(Start, function.mod, true);
    function.start = Start - moduleBase;
    function.end = End - moduleBase;
    function.manual = Manual;

    // Insert to global table
    EXCLUSIVE_ACQUIRE(LockFunctions);

    functions.insert(std::make_pair(ModuleRange(ModHashFromAddr(moduleBase), Range(function.start, function.end)), function));
    return true;
}
Ejemplo n.º 3
0
bool ArgumentAdd(duint Start, duint End, bool Manual, duint InstructionCount)
{
    // Make sure memory is readable
    if(!MemIsValidReadPtr(Start))
        return false;

    // Fail if boundary exceeds module size
    auto moduleBase = ModBaseFromAddr(Start);

    if(moduleBase != ModBaseFromAddr(End))
        return false;

    // Fail if 'Start' and 'End' are incompatible
    if(Start > End || ArgumentOverlaps(Start, End))
        return false;

    ARGUMENTSINFO argument;
    if(!ModNameFromAddr(Start, argument.mod, true))
        *argument.mod = '\0';
    argument.start = Start - moduleBase;
    argument.end = End - moduleBase;
    argument.manual = Manual;
    argument.instructioncount = InstructionCount;

    return arguments.Add(argument);
}
Ejemplo n.º 4
0
void StackEntryFromFrame(CALLSTACKENTRY* Entry, uint Address, uint From, uint To)
{
    Entry->addr = Address;
    Entry->from = From;
    Entry->to = To;

    char label[MAX_LABEL_SIZE] = "";
    ADDRINFO addrinfo;
    addrinfo.flags = flaglabel;
    if(_dbg_addrinfoget(Entry->to, SEG_DEFAULT, &addrinfo))
        strcpy_s(label, addrinfo.label);
    char module[MAX_MODULE_SIZE] = "";
    ModNameFromAddr(Entry->to, module, false);
    char returnToAddr[MAX_COMMENT_SIZE] = "";
    if(*module)
        sprintf(returnToAddr, "%s.", module);
    if(!*label)
        sprintf(label, fhex, Entry->to);
    strcat(returnToAddr, label);

    if(Entry->from)
    {
        *label = 0;
        addrinfo.flags = flaglabel;
        if(_dbg_addrinfoget(Entry->from, SEG_DEFAULT, &addrinfo))
            strcpy_s(label, addrinfo.label);
        *module = 0;
        ModNameFromAddr(Entry->from, module, false);
        char returnFromAddr[MAX_COMMENT_SIZE] = "";
        if(*module)
            sprintf(returnFromAddr, "%s.", module);
        if(!*label)
            sprintf(label, fhex, Entry->from);
        strcat(returnFromAddr, label);

        sprintf_s(Entry->comment, "return to %s from %s", returnToAddr, returnFromAddr);
    }
    else
        sprintf_s(Entry->comment, "return to %s from ???", returnToAddr);
}
Ejemplo n.º 5
0
bool PatchSet(duint Address, unsigned char OldByte, unsigned char NewByte)
{
    ASSERT_DEBUGGING("Export call");

    // Address must be valid
    if(!MemIsValidReadPtr(Address))
        return false;

    // Don't patch anything if the new and old values are the same
    if(OldByte == NewByte)
        return true;

    PATCHINFO newPatch;
    newPatch.addr = Address - ModBaseFromAddr(Address);
    newPatch.oldbyte = OldByte;
    newPatch.newbyte = NewByte;
    ModNameFromAddr(Address, newPatch.mod, true);

    // Generate a key for this address
    const duint key = ModHashFromAddr(Address);

    EXCLUSIVE_ACQUIRE(LockPatches);

    // Find any patch with this specific address
    auto found = patches.find(key);

    if(found != patches.end())
    {
        if(found->second.oldbyte == NewByte)
        {
            // The patch was undone here
            patches.erase(found);
            return true;
        }

        // Keep the original byte from the previous patch
        newPatch.oldbyte = found->second.oldbyte;
        found->second = newPatch;
    }
    else
    {
        // The entry was never found, insert it
        patches.insert(std::make_pair(key, newPatch));
    }

    return true;
}
Ejemplo n.º 6
0
const char* SymGetSymbolicName(uint Address)
{
    //
    // This resolves an address to a module and symbol:
    // [modname.]symbolname
    //
    char label[MAX_SYM_NAME];

    // User labels have priority, but if one wasn't found,
    // default to a symbol lookup
    if(!LabelGet(Address, label))
    {
        char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];

        PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
        symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
        symbol->MaxNameLen = MAX_LABEL_SIZE;

        // Perform a symbol lookup
        DWORD64 displacement = 0;

        if(!SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)Address, &displacement, symbol))
            return nullptr;

        // If the symbol wasn't at offset 0 (start from the beginning) ignore it
        if(displacement != 0)
            return nullptr;

        // Terminate the string for sanity
        symbol->Name[symbol->MaxNameLen - 1] = '\0';

        if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(symbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
            strcpy_s(label, symbol->Name);
    }

    // TODO: FIXME: STATIC VARIABLE
    static char symbolicname[MAX_MODULE_SIZE + MAX_SYM_NAME];
    char modname[MAX_MODULE_SIZE];

    if(ModNameFromAddr(Address, modname, false))
        sprintf_s(symbolicname, "%s.%s", modname, label);
    else
        sprintf_s(symbolicname, "<%s>", label);

    return symbolicname;
}
Ejemplo n.º 7
0
bool LoopAdd(uint Start, uint End, bool Manual)
{
    // CHECK: Export function
    if(!DbgIsDebugging())
        return false;

    // Loop must begin before it ends
    if(Start > End)
        return false;

    // Memory addresses must be valid
    if(!MemIsValidReadPtr(Start) || !MemIsValidReadPtr(End))
        return false;

    // Check if loop boundaries are in the same module range
    const uint moduleBase = ModBaseFromAddr(Start);

    if(moduleBase != ModBaseFromAddr(End))
        return false;

    // Loops cannot overlap other loops
    int finalDepth = 0;

    if(LoopOverlaps(0, Start, End, &finalDepth))
        return false;

    // Fill out loop information structure
    LOOPSINFO loopInfo;
    loopInfo.start = Start - moduleBase;
    loopInfo.end = End - moduleBase;
    loopInfo.depth = finalDepth;
    loopInfo.manual = Manual;
    ModNameFromAddr(Start, loopInfo.mod, true);

    // Link this to a parent loop if one does exist
    if(finalDepth)
        LoopGet(finalDepth - 1, Start, &loopInfo.parent, 0);
    else
        loopInfo.parent = 0;

    EXCLUSIVE_ACQUIRE(LockLoops);

    // Insert into list
    loops.insert(std::make_pair(DepthModuleRange(finalDepth, ModuleRange(ModHashFromAddr(moduleBase), Range(loopInfo.start, loopInfo.end))), loopInfo));
    return true;
}
Ejemplo n.º 8
0
bool LabelSet(uint Address, const char* Text, bool Manual)
{
    // CHECK: Exported/Command function
    if(!DbgIsDebugging())
        return false;

    // A valid memory address must be supplied
    if(!MemIsValidReadPtr(Address))
        return false;

    // Make sure the string is supplied, within bounds, and not a special delimiter
    if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_LABEL_SIZE - 1)
        return false;

    // Labels cannot be "address" of actual variables
    if(strstr(Text, "&"))
        return false;

    // Delete the label if no text was supplied
    if(Text[0] == '\0')
        return LabelDelete(Address);

    // Fill out the structure data
    LABELSINFO labelInfo;
    labelInfo.manual = Manual;
    labelInfo.addr = Address - ModBaseFromAddr(Address);
    strcpy_s(labelInfo.text, Text);
    ModNameFromAddr(Address, labelInfo.mod, true);

    EXCLUSIVE_ACQUIRE(LockLabels);

    // Insert label by key
    const uint key = ModHashFromAddr(Address);

    if(!labels.insert(std::make_pair(ModHashFromAddr(key), labelInfo)).second)
        labels[key] = labelInfo;

    return true;
}
Ejemplo n.º 9
0
bool CommentSet(uint Address, const char* Text, bool Manual)
{
    // CHECK: Exported/Command function
    if(!DbgIsDebugging())
        return false;

    // A valid memory address must be supplied
    if(!MemIsValidReadPtr(Address))
        return false;

    // Make sure the string is supplied, within bounds, and not a special delimiter
    if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_COMMENT_SIZE - 1)
        return false;

    // Delete the comment if no text was supplied
    if(Text[0] == '\0')
        return CommentDelete(Address);

    // Fill out the structure
    COMMENTSINFO comment;
    strcpy_s(comment.text, Text);
    ModNameFromAddr(Address, comment.mod, true);

    comment.manual = Manual;
    comment.addr = Address - ModBaseFromAddr(Address);

    // Key generated from module hash
    const uint key = ModHashFromAddr(Address);

    EXCLUSIVE_ACQUIRE(LockComments);

    // Insert if possible, otherwise replace
    if(!comments.insert(std::make_pair(key, comment)).second)
        comments[key] = comment;

    return true;
}
Ejemplo n.º 10
0
///api functions
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
{
    MEMORY_BASIC_INFORMATION mbi;
    VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi));
    uint size = mbi.RegionSize;
    Memory<void*> buffer(size, "apienumexports:buffer");
    if(!MemRead((void*)base, buffer, size, 0))
        return false;
    IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((uint)buffer + GetPE32DataFromMappedFile((ULONG_PTR)buffer, 0, UE_PE_OFFSET));
    uint export_dir_rva = pnth->OptionalHeader.DataDirectory[0].VirtualAddress;
    uint export_dir_size = pnth->OptionalHeader.DataDirectory[0].Size;
    IMAGE_EXPORT_DIRECTORY export_dir;
    memset(&export_dir, 0, sizeof(export_dir));
    MemRead((void*)(export_dir_rva + base), &export_dir, sizeof(export_dir), 0);
    unsigned int NumberOfNames = export_dir.NumberOfNames;
    if(!export_dir.NumberOfFunctions or !NumberOfNames) //no named exports
        return false;
    char modname[MAX_MODULE_SIZE] = "";
    ModNameFromAddr(base, modname, true);
    uint original_name_va = export_dir.Name + base;
    char original_name[deflen] = "";
    memset(original_name, 0, sizeof(original_name));
    MemRead((void*)original_name_va, original_name, deflen, 0);
    char* AddrOfFunctions_va = (char*)(export_dir.AddressOfFunctions + base);
    char* AddrOfNames_va = (char*)(export_dir.AddressOfNames + base);
    char* AddrOfNameOrdinals_va = (char*)(export_dir.AddressOfNameOrdinals + base);
    for(DWORD i = 0; i < NumberOfNames; i++)
    {
        DWORD curAddrOfName = 0;
        MemRead(AddrOfNames_va + sizeof(DWORD)*i, &curAddrOfName, sizeof(DWORD), 0);
        char* cur_name_va = (char*)(curAddrOfName + base);
        char cur_name[deflen] = "";
        memset(cur_name, 0, deflen);
        MemRead(cur_name_va, cur_name, deflen, 0);
        WORD curAddrOfNameOrdinals = 0;
        MemRead(AddrOfNameOrdinals_va + sizeof(WORD)*i, &curAddrOfNameOrdinals, sizeof(WORD), 0);
        DWORD curFunctionRva = 0;
        MemRead(AddrOfFunctions_va + sizeof(DWORD)*curAddrOfNameOrdinals, &curFunctionRva, sizeof(DWORD), 0);

        if(curFunctionRva >= export_dir_rva and curFunctionRva < export_dir_rva + export_dir_size)
        {
            char forwarded_api[deflen] = "";
            memset(forwarded_api, 0, deflen);
            MemRead((void*)(curFunctionRva + base), forwarded_api, deflen, 0);
            int len = (int)strlen(forwarded_api);
            int j = 0;
            while(forwarded_api[j] != '.' and j < len)
                j++;
            if(forwarded_api[j] == '.')
            {
                forwarded_api[j] = 0;
                HINSTANCE hTempDll = LoadLibraryExA(forwarded_api, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
                if(hTempDll)
                {
                    uint local_addr = (uint)GetProcAddress(hTempDll, forwarded_api + j + 1);
                    if(local_addr)
                    {
                        uint remote_addr = ImporterGetRemoteAPIAddress(fdProcessInfo->hProcess, local_addr);
                        cbEnum(base, modname, cur_name, remote_addr);
                    }
                }
            }
        }
        else
        {
            cbEnum(base, modname, cur_name, curFunctionRva + base);
        }
    }
    return true;
}
Ejemplo n.º 11
0
bool stackcommentget(duint addr, STACK_COMMENT* comment)
{
    SHARED_ACQUIRE(LockSehCache);
    const auto found = SehCache.find(addr);
    if(found != SehCache.end())
    {
        *comment = found->second;
        return true;
    }
    SHARED_RELEASE();

    duint data = 0;
    memset(comment, 0, sizeof(STACK_COMMENT));
    MemRead(addr, &data, sizeof(duint));
    if(!MemIsValidReadPtr(data)) //the stack value is no pointer
        return false;

    duint size = 0;
    duint base = MemFindBaseAddr(data, &size);
    duint readStart = data - 16 * 4;
    if(readStart < base)
        readStart = base;
    unsigned char disasmData[256];
    MemRead(readStart, disasmData, sizeof(disasmData));
    duint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1);
    duint previousInstr = readStart + prev;

    BASIC_INSTRUCTION_INFO basicinfo;
    bool valid = disasmfast(disasmData + prev, previousInstr, &basicinfo);
    if(valid && basicinfo.call) //call
    {
        char label[MAX_LABEL_SIZE] = "";
        ADDRINFO addrinfo;
        addrinfo.flags = flaglabel;
        if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
            strcpy_s(label, addrinfo.label);
        char module[MAX_MODULE_SIZE] = "";
        ModNameFromAddr(data, module, false);
        char returnToAddr[MAX_COMMENT_SIZE] = "";
        if(*module)
            sprintf(returnToAddr, "%s.", module);
        if(!*label)
            sprintf_s(label, "%p", data);
        strcat(returnToAddr, label);

        data = basicinfo.addr;
        if(data)
        {
            *label = 0;
            addrinfo.flags = flaglabel;
            if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
                strcpy_s(label, addrinfo.label);
            *module = 0;
            ModNameFromAddr(data, module, false);
            char returnFromAddr[MAX_COMMENT_SIZE] = "";
            if(*module)
                sprintf_s(returnFromAddr, "%s.", module);
            if(!*label)
                sprintf_s(label, "%p", data);
            strcat_s(returnFromAddr, label);
            sprintf_s(comment->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from %s")), returnToAddr, returnFromAddr);
        }
        else
            sprintf_s(comment->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from ???")), returnToAddr);
        strcpy_s(comment->color, "!rtnclr"); // Special token for return address color;
        return true;
    }

    //string
    char string[MAX_STRING_SIZE] = "";
    if(DbgGetStringAt(data, string))
    {
        strncpy_s(comment->comment, string, _TRUNCATE);
        return true;
    }

    //label
    char label[MAX_LABEL_SIZE] = "";
    ADDRINFO addrinfo;
    addrinfo.flags = flaglabel;
    if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
        strcpy_s(label, addrinfo.label);
    char module[MAX_MODULE_SIZE] = "";
    ModNameFromAddr(data, module, false);

    if(*module) //module
    {
        if(*label) //+label
            sprintf_s(comment->comment, "%s.%s", module, label);
        else //module only
            sprintf_s(comment->comment, "%s.%p", module, data);
        return true;
    }
    else if(*label) //label only
    {
        sprintf_s(comment->comment, "<%s>", label);
        return true;
    }

    return false;
}
Ejemplo n.º 12
0
bool stackcommentget(uint addr, STACK_COMMENT* comment)
{
    uint data = 0;
    memset(comment, 0, sizeof(STACK_COMMENT));
    MemRead(addr, &data, sizeof(uint));
    if(!MemIsValidReadPtr(data)) //the stack value is no pointer
        return false;

    uint size = 0;
    uint base = MemFindBaseAddr(data, &size);
    uint readStart = data - 16 * 4;
    if(readStart < base)
        readStart = base;
    unsigned char disasmData[256];
    MemRead(readStart, disasmData, sizeof(disasmData));
    uint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1);
    uint previousInstr = readStart + prev;

    BASIC_INSTRUCTION_INFO basicinfo;
    bool valid = disasmfast(disasmData + prev, previousInstr, &basicinfo);
    if(valid && basicinfo.call) //call
    {
        char label[MAX_LABEL_SIZE] = "";
        ADDRINFO addrinfo;
        addrinfo.flags = flaglabel;
        if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
            strcpy_s(label, addrinfo.label);
        char module[MAX_MODULE_SIZE] = "";
        ModNameFromAddr(data, module, false);
        char returnToAddr[MAX_COMMENT_SIZE] = "";
        if(*module)
            sprintf(returnToAddr, "%s.", module);
        if(!*label)
            sprintf(label, fhex, data);
        strcat(returnToAddr, label);

        data = basicinfo.addr;
        if(data)
        {
            *label = 0;
            addrinfo.flags = flaglabel;
            if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
                strcpy_s(label, addrinfo.label);
            *module = 0;
            ModNameFromAddr(data, module, false);
            char returnFromAddr[MAX_COMMENT_SIZE] = "";
            if(*module)
                sprintf(returnFromAddr, "%s.", module);
            if(!*label)
                sprintf(label, fhex, data);
            strcat_s(returnFromAddr, label);
            sprintf_s(comment->comment, "return to %s from %s", returnToAddr, returnFromAddr);
        }
        else
            sprintf_s(comment->comment, "return to %s from ???", returnToAddr);
        strcpy_s(comment->color, "#ff0000");
        return true;
    }

    //string
    STRING_TYPE strtype;
    char string[512] = "";
    if(disasmgetstringat(data, &strtype, string, string, 500))
    {
        if(strtype == str_ascii)
            sprintf(comment->comment, "\"%s\"", string);
        else //unicode
            sprintf(comment->comment, "L\"%s\"", string);
        return true;
    }

    //label
    char label[MAX_LABEL_SIZE] = "";
    ADDRINFO addrinfo;
    addrinfo.flags = flaglabel;
    if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
        strcpy_s(label, addrinfo.label);
    char module[MAX_MODULE_SIZE] = "";
    ModNameFromAddr(data, module, false);

    if(*module) //module
    {
        if(*label) //+label
            sprintf(comment->comment, "%s.%s", module, label);
        else //module only
            sprintf(comment->comment, "%s." fhex, module, data);
        return true;
    }
    else if(*label) //label only
    {
        sprintf(comment->comment, "<%s>", label);
        return true;
    }

    return false;
}
Ejemplo n.º 13
0
int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name, REFFINDTYPE type)
{
    char fullName[deflen];
    char moduleName[MAX_MODULE_SIZE];
    duint scanStart, scanSize;
    REFINFO refInfo;

    if(type == CURRENT_REGION) // Search in current Region
    {
        duint regionSize = 0;
        duint regionBase = MemFindBaseAddr(Address, &regionSize, true);

        // If the memory page wasn't found, fail
        if(!regionBase || !regionSize)
        {
            if(!Silent)
                dprintf("Invalid memory page 0x%p\n", Address);

            return 0;
        }

        // Assume the entire range is used
        scanStart = regionBase;
        scanSize  = regionSize;

        // Otherwise use custom boundaries if size was supplied
        if(Size)
        {
            duint maxsize = Size - (Address - regionBase);

            // Make sure the size fits in one page
            scanStart = Address;
            scanSize  = min(Size, maxsize);
        }

        // Determine the full module name
        if(ModNameFromAddr(scanStart, moduleName, true))
            sprintf_s(fullName, "%s (Region %s)", Name, moduleName);
        else
            sprintf_s(fullName, "%s (Region %p)", Name, scanStart);

        // Initialize disassembler
        Capstone cp;

        // Allow an "initialization" notice
        refInfo.refcount = 0;
        refInfo.userinfo = UserData;
        refInfo.name = fullName;

        RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, true, [](int percent)
        {
            GuiReferenceSetCurrentTaskProgress(percent, "Region Search");
            GuiReferenceSetProgress(percent);
        });
    }
    else if(type == CURRENT_MODULE) // Search in current Module
    {
        SHARED_ACQUIRE(LockModules);
        auto modInfo = ModInfoFromAddr(Address);

        if(!modInfo)
        {
            if(!Silent)
                dprintf("Couldn't locate module for 0x%p\n", Address);

            return 0;
        }

        duint modBase = modInfo->base;
        duint modSize = modInfo->size;

        SHARED_RELEASE();

        scanStart = modBase;
        scanSize  = modSize;

        // Determine the full module name
        if(ModNameFromAddr(scanStart, moduleName, true))
            sprintf_s(fullName, "%s (%s)", Name, moduleName);
        else
            sprintf_s(fullName, "%s (%p)", Name, scanStart);

        // Initialize disassembler
        Capstone cp;

        // Allow an "initialization" notice
        refInfo.refcount = 0;
        refInfo.userinfo = UserData;
        refInfo.name = fullName;

        RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, true, [](int percent)
        {
            GuiReferenceSetCurrentTaskProgress(percent, "Module Search");
            GuiReferenceSetProgress(percent);
        });
    }
    else if(type == ALL_MODULES) // Search in all Modules
    {
        bool initCallBack = true;
        std::vector<MODINFO> modList;
        ModGetList(modList);

        if(!modList.size())
        {
            if(!Silent)
                dprintf("Couldn't get module list");

            return 0;
        }

        // Initialize disassembler
        Capstone cp;

        // Determine the full module
        sprintf_s(fullName, "All Modules (%s)", Name);

        // Allow an "initialization" notice
        refInfo.refcount = 0;
        refInfo.userinfo = UserData;
        refInfo.name = fullName;

        for(duint i = 0; i < modList.size(); i++)
        {
            scanStart = modList[i].base;
            scanSize  = modList[i].size;

            if(i != 0)
                initCallBack = false;

            RefFindInRange(scanStart, scanSize, Callback, UserData, Silent, refInfo, cp, initCallBack, [&i, &modList](int percent)
            {
                float fPercent = (float)percent / 100.f;
                float fTotalPercent = ((float)i + fPercent) / (float)modList.size();

                int totalPercent = (int)floor(fTotalPercent * 100.f);

                char tst[256];
                strcpy_s(tst, modList[i].name);

                GuiReferenceSetCurrentTaskProgress(percent, modList[i].name);
                GuiReferenceSetProgress(totalPercent);
            });
        }
    }

    GuiReferenceSetProgress(100);
    GuiReferenceReloadData();
    return refInfo.refcount;
}
Ejemplo n.º 14
0
SCRIPT_EXPORT bool Script::Module::NameFromAddr(duint addr, char* name)
{
    return ModNameFromAddr(addr, name, true);
}
Ejemplo n.º 15
0
extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo)
{
    if(!DbgIsDebugging())
        return false;
    bool retval = false;
    if(addrinfo->flags & flagmodule) //get module
    {
        if(ModNameFromAddr(addr, addrinfo->module, false)) //get module name
            retval = true;
    }
    if(addrinfo->flags & flaglabel)
    {
        if(LabelGet(addr, addrinfo->label))
            retval = true;
        else //no user labels
        {
            DWORD64 displacement = 0;
            char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
            PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
            pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
            pSymbol->MaxNameLen = MAX_LABEL_SIZE;
            if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) && !displacement)
            {
                pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
                if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
                    strcpy_s(addrinfo->label, pSymbol->Name);
                retval = true;
            }
            if(!retval) //search for CALL <jmp.&user32.MessageBoxA>
            {
                BASIC_INSTRUCTION_INFO basicinfo;
                memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO));
                if(disasmfast(addr, &basicinfo) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP
                {
                    uint val = 0;
                    if(MemRead(basicinfo.memory.value, &val, sizeof(val)))
                    {
                        if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) && !displacement)
                        {
                            pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
                            if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
                                sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name);
                            retval = true;
                        }
                    }
                }
            }
            if(!retval)  //search for module entry
            {
                uint entry = ModEntryFromAddr(addr);
                if(entry && entry == addr)
                {
                    strcpy_s(addrinfo->label, "EntryPoint");
                    retval = true;
                }
            }
        }
    }
    if(addrinfo->flags & flagbookmark)
    {
        addrinfo->isbookmark = BookmarkGet(addr);
        retval = true;
    }
    if(addrinfo->flags & flagfunction)
    {
        if(FunctionGet(addr, &addrinfo->function.start, &addrinfo->function.end))
            retval = true;
    }
    if(addrinfo->flags & flagloop)
    {
        if(LoopGet(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end))
            retval = true;
    }
    if(addrinfo->flags & flagcomment)
    {
        *addrinfo->comment = 0;
        if(CommentGet(addr, addrinfo->comment))
            retval = true;
        else
        {
            DWORD dwDisplacement;
            IMAGEHLP_LINE64 line;
            line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
            if(SafeSymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) && !dwDisplacement)
            {
                char filename[deflen] = "";
                strcpy_s(filename, line.FileName);
                int len = (int)strlen(filename);
                while(filename[len] != '\\' && len != 0)
                    len--;
                if(len)
                    len++;
                sprintf_s(addrinfo->comment, "\1%s:%u", filename + len, line.LineNumber);
                retval = true;
            }
            else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number
            {
                DISASM_INSTR instr;
                String temp_string;
                String comment;
                ADDRINFO newinfo;
                char ascii[256 * 2] = "";
                char unicode[256 * 2] = "";

                memset(&instr, 0, sizeof(DISASM_INSTR));
                disasmget(addr, &instr);
                int len_left = MAX_COMMENT_SIZE;
                for(int i = 0; i < instr.argcount; i++)
                {
                    memset(&newinfo, 0, sizeof(ADDRINFO));
                    newinfo.flags = flaglabel;

                    STRING_TYPE strtype = str_none;

                    if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
                    {
                        if(instr.type == instr_branch || !disasmgetstringat(instr.arg[i].constant, &strtype, ascii, unicode, len_left) || strtype == str_none)
                            continue;
                        switch(strtype)
                        {
                        case str_none:
                            break;
                        case str_ascii:
                            temp_string = instr.arg[i].mnemonic;
                            temp_string.append(":\"");
                            temp_string.append(ascii);
                            temp_string.append("\"");
                            break;
                        case str_unicode:
                            temp_string = instr.arg[i].mnemonic;
                            temp_string.append(":L\"");
                            temp_string.append(unicode);
                            temp_string.append("\"");
                            break;
                        }
                    }
                    else if(instr.arg[i].memvalue && (disasmgetstringat(instr.arg[i].memvalue, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo)))
                    {
                        switch(strtype)
                        {
                        case str_none:
                            if(*newinfo.label)
                            {
                                temp_string = "[";
                                temp_string.append(instr.arg[i].mnemonic);
                                temp_string.append("]:");
                                temp_string.append(newinfo.label);
                            }
                            break;
                        case str_ascii:
                            temp_string = "[";
                            temp_string.append(instr.arg[i].mnemonic);
                            temp_string.append("]:");
                            temp_string.append(ascii);
                            break;
                        case str_unicode:
                            temp_string = "[";
                            temp_string.append(instr.arg[i].mnemonic);
                            temp_string.append("]:");
                            temp_string.append(unicode);
                            break;
                        }
                    }
                    else if(instr.arg[i].value && (disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo)))
                    {
                        if(instr.type != instr_normal) //stack/jumps (eg add esp,4 or jmp 401110) cannot directly point to strings
                            strtype = str_none;
                        switch(strtype)
                        {
                        case str_none:
                            if(*newinfo.label)
                            {
                                temp_string = instr.arg[i].mnemonic;
                                temp_string.append(":");
                                temp_string.append(newinfo.label);
                            }
                            break;
                        case str_ascii:
                            temp_string = instr.arg[i].mnemonic;
                            temp_string.append(":\"");
                            temp_string.append(ascii);
                            temp_string.append("\"");
                            break;
                        case str_unicode:
                            temp_string = instr.arg[i].mnemonic;
                            temp_string.append(":L\"");
                            temp_string.append(unicode);
                            temp_string.append("\"");
                            break;
                        }
                    }
                    else
                        continue;

                    if(!strstr(comment.c_str(), temp_string.c_str()))
                    {
                        if(comment.length())
                            comment.append(", ");
                        comment.append(temp_string);
                        retval = true;
                    }
                }
                comment.resize(MAX_COMMENT_SIZE - 2);
                String fullComment = "\1";
                fullComment += comment;
                strcpy_s(addrinfo->comment, fullComment.c_str());
            }
        }
    }
    return retval;
}