Example #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;
}
Example #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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
bool FunctionDelete(uint Address)
{
    // CHECK: Exported function
    if(!DbgIsDebugging())
        return false;

    const uint moduleBase = ModBaseFromAddr(Address);

    EXCLUSIVE_ACQUIRE(LockFunctions);
    return (functions.erase(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase))) > 0);
}
Example #6
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);
}
Example #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;
}
Example #8
0
void FunctionCacheLoad(JSON Root)
{
    EXCLUSIVE_ACQUIRE(LockFunctions);

    // Delete existing entries
    functions.clear();

    // Inline lambda to enumerate all JSON array indices
    auto InsertFunctions = [](const JSON Object, bool Manual)
    {
        size_t i;
        JSON value;
        json_array_foreach(Object, i, value)
        {
            FUNCTIONSINFO functionInfo;
            memset(&functionInfo, 0, sizeof(FUNCTIONSINFO));

            // Copy module name
            const char* mod = json_string_value(json_object_get(value, "module"));

            if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
                strcpy_s(functionInfo.mod, mod);

            // Function address
            functionInfo.start = (uint)json_hex_value(json_object_get(value, "start"));
            functionInfo.end = (uint)json_hex_value(json_object_get(value, "end"));
            functionInfo.manual = Manual;

            // Sanity check
            if(functionInfo.end < functionInfo.start)
                continue;

            const uint key = ModHashFromName(functionInfo.mod);
            functions.insert(std::make_pair(ModuleRange(key, Range(functionInfo.start, functionInfo.end)), functionInfo));
        }
    };
Example #9
0
void LoopCacheLoad(JSON Root)
{
    EXCLUSIVE_ACQUIRE(LockLoops);

    // Inline lambda to parse each JSON entry
    auto AddLoops = [](const JSON Object, bool Manual)
    {
        size_t i;
        JSON value;

        json_array_foreach(Object, i, value)
        {
            LOOPSINFO loopInfo;
            memset(&loopInfo, 0, sizeof(LOOPSINFO));

            // Module name
            const char* mod = json_string_value(json_object_get(value, "module"));

            if(mod && strlen(mod) < MAX_MODULE_SIZE)
                strcpy_s(loopInfo.mod, mod);

            // All other variables
            loopInfo.start = (duint)json_hex_value(json_object_get(value, "start"));
            loopInfo.end = (duint)json_hex_value(json_object_get(value, "end"));
            loopInfo.depth = (int)json_integer_value(json_object_get(value, "depth"));
            loopInfo.parent = (duint)json_hex_value(json_object_get(value, "parent"));
            loopInfo.manual = Manual;

            // Sanity check: Make sure the loop starts before it ends
            if(loopInfo.end < loopInfo.start)
                continue;

            // Insert into global list
            loops.insert(std::make_pair(DepthModuleRange(loopInfo.depth, ModuleRange(ModHashFromName(loopInfo.mod), Range(loopInfo.start, loopInfo.end))), loopInfo));
        }
    };
Example #10
0
 ModuleRange makeKey(const ARGUMENTSINFO & value) const override
 {
     return ModuleRange(ModHashFromName(value.mod), Range(value.start, value.end));
 }