Esempio n. 1
0
// Get the start/end of a loop at a certain depth and address
bool LoopGet(int Depth, duint Address, duint* Start, duint* End)
{
    ASSERT_DEBUGGING("Export call");

    // Get the virtual address module
    const duint moduleBase = ModBaseFromAddr(Address);

    // Virtual address to relative address
    Address -= moduleBase;

    SHARED_ACQUIRE(LockLoops);

    // Search with this address range
    auto found = loops.find(DepthModuleRange(Depth, ModuleRange(ModHashFromAddr(moduleBase), Range(Address, Address))));

    if(found == loops.end())
        return false;

    // Return the loop start and end
    if(Start)
        *Start = found->second.start + moduleBase;

    if(End)
        *End = found->second.end + moduleBase;

    return true;
}
Esempio n. 2
0
/**
\brief Enumerates all variables.
\param [in,out] List A pointer to place the variables in. If null, \p cbsize will be filled to the number of bytes required.
\param [in,out] Size This function retrieves the number of bytes required to store all variables. Can be null if \p entries is not null.
\return true if it succeeds, false if it fails.
*/
bool varenum(VAR* List, size_t* Size)
{
    // A list or size must be requested
    if(!List && !Size)
        return false;

    SHARED_ACQUIRE(LockVariables);

    if(Size)
    {
        // Size requested, so return it
        *Size = variables.size() * sizeof(VAR);

        if(!List)
            return true;
    }

    // Fill out all list entries
    for(auto & itr : variables)
    {
        *List = itr.second;
        List++;
    }

    return true;
}
Esempio n. 3
0
bool PatchEnum(PATCHINFO* List, size_t* Size)
{
    ASSERT_DEBUGGING("Export call");
    ASSERT_FALSE(!List && !Size);
    SHARED_ACQUIRE(LockPatches);

    // Did the user request the size?
    if(Size)
    {
        *Size = patches.size() * sizeof(PATCHINFO);

        if(!List)
            return true;
    }

    // Copy each vector entry to a C-style array
    for(auto & itr : patches)
    {
        *List = itr.second;
        List->addr += ModBaseFromName(itr.second.mod);;
        List++;
    }

    return true;
}
Esempio n. 4
0
bool FunctionGet(uint Address, uint* Start, uint* End)
{
    // CHECK: Exported function
    if(!DbgIsDebugging())
        return false;

    const uint moduleBase = ModBaseFromAddr(Address);

    // Lookup by module hash, then function range
    SHARED_ACQUIRE(LockFunctions);

    auto found = functions.find(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase)));

    // Was this range found?
    if(found == functions.end())
        return false;

    if(Start)
        *Start = found->second.start + moduleBase;

    if(End)
        *End = found->second.end + moduleBase;

    return true;
}
Esempio n. 5
0
/**
\brief Gets a variable value.
\param Name The name of the variable.
\param [out] Value This function can get the variable value. If this value is null, it is ignored.
\param [out] Size This function can get the variable size. If this value is null, it is ignored.
\param [out] Type This function can get the variable type. If this value is null, it is ignored.
\return true if the variable was found and the optional values were retrieved successfully, false otherwise.
*/
bool varget(const char* Name, VAR_VALUE* Value, int* Size, VAR_TYPE* Type)
{
    SHARED_ACQUIRE(LockVariables);

    String name_;
    if(*Name != '$')
        name_ = "$";
    name_ += Name;
    auto found = variables.find(name_);
    if(found == variables.end()) //not found
        return false;
    if(found->second.alias.length())
    {
        // Release the lock (potential deadlock here)
        SHARED_RELEASE();

        return varget(found->second.alias.c_str(), Value, Size, Type);
    }
    if(Type)
        *Type = found->second.type;
    if(Size)
        *Size = found->second.value.size;
    if(Value)
        *Value = found->second.value;
    return true;
}
Esempio n. 6
0
// Get the start/end of a loop at a certain depth and address
bool LoopGet(int Depth, uint Address, uint* Start, uint* End)
{
    // CHECK: Exported function
    if(!DbgIsDebugging())
        return false;

    // Get the virtual address module
    const uint moduleBase = ModBaseFromAddr(Address);

    // Virtual address to relative address
    Address -= moduleBase;

    SHARED_ACQUIRE(LockLoops);

    // Search with this address range
    auto found = loops.find(DepthModuleRange(Depth, ModuleRange(ModHashFromAddr(moduleBase), Range(Address, Address))));

    if(found == loops.end())
        return false;

    // Return the loop start
    if(Start)
        *Start = found->second.start + moduleBase;

    // Also the loop end
    if(End)
        *End = found->second.end + moduleBase;

    return true;
}
Esempio n. 7
0
DWORD ThreadGetLastError(DWORD ThreadId)
{
    SHARED_ACQUIRE(LockThreads);

    if(threadList.find(ThreadId) != threadList.end())
        return ThreadGetLastErrorTEB(threadList[ThreadId].ThreadLocalBase);

    ASSERT_ALWAYS("Trying to get last error of a thread that doesn't exist!");
    return 0;
}
Esempio n. 8
0
HANDLE ThreadGetHandle(DWORD ThreadId)
{
    SHARED_ACQUIRE(LockThreads);

    if(threadList.find(ThreadId) != threadList.end())
        return threadList[ThreadId].Handle;

    ASSERT_ALWAYS("Trying to get handle of a thread that doesn't exist!");
    return nullptr;
}
Esempio n. 9
0
uint ModEntryFromAddr(uint Address)
{
    SHARED_ACQUIRE(LockModules);

    auto module = ModInfoFromAddr(Address);

    if(!module)
        return 0;

    return module->entry;
}
Esempio n. 10
0
uint ModSizeFromAddr(uint Address)
{
    SHARED_ACQUIRE(LockModules);

    auto module = ModInfoFromAddr(Address);

    if(!module)
        return 0;

    return module->size;
}
Esempio n. 11
0
SCRIPT_EXPORT bool Script::Module::SectionFromAddr(duint addr, int number, ModuleSectionInfo* section)
{
    SHARED_ACQUIRE(LockModules);
    MODINFO* modInfo = ModInfoFromAddr(addr);
    if(!section || !modInfo || number < 0 || number >= int(modInfo->sections.size()))
        return false;
    const MODSECTIONINFO & secInfo = modInfo->sections.at(number);
    section->addr = secInfo.addr;
    section->size = secInfo.size;
    strcpy_s(section->name, secInfo.name);
    return true;
}
Esempio n. 12
0
int ModPathFromAddr(duint Address, char* Path, int Size)
{
    SHARED_ACQUIRE(LockModules);

    auto module = ModInfoFromAddr(Address);

    if(!module)
        return 0;

    strcpy_s(Path, Size, module->path);
    return (int)strlen(Path);
}
Esempio n. 13
0
bool ModSectionsFromAddr(uint Address, std::vector<MODSECTIONINFO>* Sections)
{
    SHARED_ACQUIRE(LockModules);

    auto module = ModInfoFromAddr(Address);

    if(!module)
        return false;

    // Copy vector <-> vector
    *Sections = module->sections;
    return true;
}
Esempio n. 14
0
//check if a loop overlaps a range, inside is not overlapping
bool LoopOverlaps(int Depth, uint Start, uint End, int* FinalDepth)
{
    // CHECK: Export function
    if(!DbgIsDebugging())
        return false;

    // Determine module addresses and lookup keys
    const uint moduleBase = ModBaseFromAddr(Start);
    const uint key = ModHashFromAddr(moduleBase);

    uint curStart = Start - moduleBase;
    uint curEnd = End - moduleBase;

    SHARED_ACQUIRE(LockLoops);

    // Check if the new loop fits in the old loop
    for(auto & itr : loops)
    {
        // Only look in the current module
        if(itr.first.second.first != key)
            continue;

        // Loop must be at this recursive depth
        if(itr.second.depth != Depth)
            continue;

        if(itr.second.start < curStart && itr.second.end > curEnd)
            return LoopOverlaps(Depth + 1, curStart, curEnd, FinalDepth);
    }

    // Did the user request t the loop depth?
    if(FinalDepth)
        *FinalDepth = Depth;

    // Check for loop overlaps
    for(auto & itr : loops)
    {
        // Only look in the current module
        if(itr.first.second.first != key)
            continue;

        // Loop must be at this recursive depth
        if(itr.second.depth != Depth)
            continue;

        if(itr.second.start <= curEnd && itr.second.end >= curStart)
            return true;
    }

    return false;
}
Esempio n. 15
0
int ThreadResumeAll()
{
    // ResumeThread does not modify any internal variables
    SHARED_ACQUIRE(LockThreads);

    int count = 0;
    for(auto & entry : threadList)
    {
        if(ResumeThread(entry.second.Handle) != -1)
            count++;
    }

    return count;
}
Esempio n. 16
0
uint ModHashFromAddr(uint Address)
{
    //
    // Returns a unique hash from a virtual address
    //
    SHARED_ACQUIRE(LockModules);

    auto module = ModInfoFromAddr(Address);

    if(!module)
        return Address;

    return module->hash + (Address - module->base);
}
Esempio n. 17
0
SCRIPT_EXPORT bool Script::Module::InfoFromAddr(duint addr, Script::Module::ModuleInfo* info)
{
    SHARED_ACQUIRE(LockModules);
    MODINFO* modInfo = ModInfoFromAddr(addr);
    if(!info || !modInfo)
        return false;
    info->base = modInfo->base;
    info->size = modInfo->size;
    info->entry = modInfo->entry;
    info->sectionCount = int(modInfo->sections.size());
    strcpy_s(info->name, modInfo->name);
    strcat_s(info->name, modInfo->extension);
    strcpy_s(info->path, modInfo->path);
    return true;
}
Esempio n. 18
0
bool FunctionOverlaps(uint Start, uint End)
{
    // CHECK: Exported function
    if(!DbgIsDebugging())
        return false;

    // A function can't end before it begins
    if(Start > End)
        return false;

    const uint moduleBase = ModBaseFromAddr(Start);

    SHARED_ACQUIRE(LockFunctions);
    return (functions.count(ModuleRange(ModHashFromAddr(moduleBase), Range(Start - moduleBase, End - moduleBase))) > 0);
}
Esempio n. 19
0
SCRIPT_EXPORT bool Script::Module::SectionListFromAddr(duint addr, ListInfo* listInfo)
{
    SHARED_ACQUIRE(LockModules);
    MODINFO* modInfo = ModInfoFromAddr(addr);
    if (!modInfo)
        return false;
    std::vector<ModuleSectionInfo> scriptSectionList(modInfo->sections.size());
    for (const auto & section : modInfo->sections)
    {
        ModuleSectionInfo scriptSection;
        scriptSection.addr = section.addr;
        scriptSection.size = section.size;
        strcpy_s(scriptSection.name, section.name);
    }
    return List<ModuleSectionInfo>::CopyData(listInfo, scriptSectionList);
}
Esempio n. 20
0
DWORD ThreadGetId(HANDLE Thread)
{
    SHARED_ACQUIRE(LockThreads);

    // Search for the ID in the local list
    for(auto & entry : threadList)
    {
        if(entry.second.Handle == Thread)
            return entry.first;
    }

    // Wasn't found, check with Windows
    typedef DWORD (WINAPI * GETTHREADID)(HANDLE hThread);
    static GETTHREADID _GetThreadId = (GETTHREADID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetThreadId");
    return _GetThreadId ? _GetThreadId(Thread) : 0;
}
Esempio n. 21
0
/**
\brief Gets a variable type.
\param Name The name of the variable. Cannot be null.
\param [out] Type This function can retrieve the variable type. If null it is ignored.
\param [out] ValueType This function can retrieve the variable value type. If null it is ignored.
\return true if getting the type was successful, false otherwise.
*/
bool vargettype(const char* Name, VAR_TYPE* Type, VAR_VALUE_TYPE* ValueType)
{
    SHARED_ACQUIRE(LockVariables);

    String name_;
    if(*Name != '$')
        name_ = "$";
    name_ += Name;
    auto found = variables.find(name_);
    if(found == variables.end()) //not found
        return false;
    if(found->second.alias.length())
        return vargettype(found->second.alias.c_str(), Type, ValueType);
    if(ValueType)
        *ValueType = found->second.value.type;
    if(Type)
        *Type = found->second.type;
    return true;
}
Esempio n. 22
0
uint ModBaseFromName(const char* Module)
{
    if(!Module || strlen(Module) >= MAX_MODULE_SIZE)
        return 0;

    SHARED_ACQUIRE(LockModules);

    for(auto itr = modinfo.begin(); itr != modinfo.end(); itr++)
    {
        char currentModule[MAX_MODULE_SIZE];
        strcpy_s(currentModule, itr->second.name);
        strcat_s(currentModule, itr->second.extension);

        // Test with and without extension
        if(!_stricmp(currentModule, Module) || !_stricmp(itr->second.name, Module))
            return itr->second.base;
    }

    return 0;
}
Esempio n. 23
0
bool LabelGet(uint Address, char* Text)
{
    // CHECK: Export function
    if(!DbgIsDebugging())
        return false;

    SHARED_ACQUIRE(LockLabels);

    // Was the label at this address exist?
    auto found = labels.find(ModHashFromAddr(Address));

    if(found == labels.end())
        return false;

    // Copy to user buffer
    if(Text)
        strcpy_s(Text, MAX_LABEL_SIZE, found->second.text);

    return true;
}
Esempio n. 24
0
bool ModNameFromAddr(uint Address, char* Name, bool Extension)
{
    if(!Name)
        return false;

    SHARED_ACQUIRE(LockModules);

    // Get a pointer to module information
    auto module = ModInfoFromAddr(Address);

    if(!module)
        return false;

    // Copy initial module name
    strcpy_s(Name, MAX_MODULE_SIZE, module->name);

    if(Extension)
        strcat_s(Name, MAX_MODULE_SIZE, module->extension);

    return true;
}
Esempio n. 25
0
bool PatchGet(duint Address, PATCHINFO* Patch)
{
    ASSERT_DEBUGGING("Export call");
    SHARED_ACQUIRE(LockPatches);

    // Find this specific address in the list
    auto found = patches.find(ModHashFromAddr(Address));

    if(found == patches.end())
        return false;

    // Did the user request an output buffer?
    if(Patch)
    {
        *Patch = found->second;
        Patch->addr += ModBaseFromAddr(Address);
    }

    // Return true because the patch was found
    return true;
}
Esempio n. 26
0
void ThreadGetList(THREADLIST* List)
{
    ASSERT_NONNULL(List);
    SHARED_ACQUIRE(LockThreads);

    //
    // This function converts a C++ std::unordered_map to a C-style THREADLIST[].
    // Also assume BridgeAlloc zeros the returned buffer.
    //
    List->count = (int)threadList.size();
    List->list = nullptr;

    if(List->count <= 0)
        return;

    // Allocate C-style array
    List->list = (THREADALLINFO*)BridgeAlloc(List->count * sizeof(THREADALLINFO));

    // Fill out the list data
    int index = 0;

    for(auto & itr : threadList)
    {
        HANDLE threadHandle = itr.second.Handle;

        // Get the debugger's active thread index
        if(threadHandle == hActiveThread)
            List->CurrentThread = index;

        memcpy(&List->list[index].BasicInfo, &itr.second, sizeof(THREADINFO));

        List->list[index].ThreadCip = GetContextDataEx(threadHandle, UE_CIP);
        List->list[index].SuspendCount = ThreadGetSuspendCount(threadHandle);
        List->list[index].Priority = ThreadGetPriority(threadHandle);
        List->list[index].WaitReason = ThreadGetWaitReason(threadHandle);
        List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase);
        index++;
    }
}
Esempio n. 27
0
extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap)
{
    SHARED_ACQUIRE(LockMemoryPages);

    int pagecount = (int)memoryPages.size();
    memset(memmap, 0, sizeof(MEMMAP));
    memmap->count = pagecount;
    if(!pagecount)
        return true;

    // Allocate memory that is already zeroed
    memmap->page = (MEMPAGE*)BridgeAlloc(sizeof(MEMPAGE) * pagecount);

    // Copy all elements over
    int i = 0;

    for(auto & itr : memoryPages)
        memcpy(&memmap->page[i++], &itr.second, sizeof(MEMPAGE));

    // Done
    return true;
}
Esempio n. 28
0
bool CommentGet(uint Address, char* Text)
{
    // CHECK: Exported/Command function
    if(!DbgIsDebugging())
        return false;

    SHARED_ACQUIRE(LockComments);

    // Get an existing comment and copy the string buffer
    auto found = comments.find(ModHashFromAddr(Address));

    // Was it found?
    if(found == comments.end())
        return false;

    if(found->second.manual)  //autocomment
        strcpy_s(Text, MAX_COMMENT_SIZE, found->second.text);
    else
        sprintf_s(Text, MAX_COMMENT_SIZE, "\1%s", found->second.text);

    return true;
}
Esempio n. 29
0
bool LabelFromString(const char* Text, uint* Address)
{
    // CHECK: Future? (Not used)
    if(!DbgIsDebugging())
        return false;

    SHARED_ACQUIRE(LockLabels);

    for(auto & itr : labels)
    {
        // Check if the actual label name matches
        if(strcmp(itr.second.text, Text))
            continue;

        if(Address)
            *Address = itr.second.addr + ModBaseFromName(itr.second.mod);

        // Set status to indicate if label was ever found
        return true;
    }

    return false;
}
Esempio n. 30
0
int ThreadGetCount()
{
    SHARED_ACQUIRE(LockThreads);
    return (int)threadList.size();
}