Esempio n. 1
0
void LinearAnalysis::AnalyseFunctions()
{
    for(size_t i = 0; i < _functions.size(); i++)
    {
        FunctionInfo & function = _functions[i];
        if(function.end)  //skip already-analysed functions
            continue;
        duint maxaddr = _base + _size;
        if(i < _functions.size() - 1)
            maxaddr = _functions[i + 1].start;

        duint end = FindFunctionEnd(function.start, maxaddr);
        if(end)
        {
            if(_cp.Disassemble(end, TranslateAddress(end), MAX_DISASM_BUFFER))
                function.end = end + _cp.Size() - 1;
            else
                function.end = end;
        }
    }
}
Esempio n. 2
0
static int l_persist_dofile(lua_State *L)
{
    const char *sFilename = luaL_checkstring(L, 1);
    lua_settop(L, 1);

    // Read entire file into memory
    FILE *fFile = fopen(sFilename, "r");
    if(fFile == NULL)
    {
        const char *sError = strerror(errno);
        return luaL_error(L, "cannot open %s: %s", sFilename, sError);
    }
    size_t iBufferSize = lua_objlen(L, lua_upvalueindex(1));
    size_t iBufferUsed = 0;
    while(!feof(fFile))
    {
        iBufferUsed += fread(reinterpret_cast<char*>(lua_touserdata(L,
            lua_upvalueindex(1))) + iBufferUsed, 1, iBufferSize - iBufferUsed, fFile);
        if(iBufferUsed == iBufferSize)
        {
            iBufferSize *= 2;
            memcpy(lua_newuserdata(L, iBufferSize), lua_touserdata(L, lua_upvalueindex(1)), iBufferUsed);
            lua_replace(L, lua_upvalueindex(1));
        }
        else
            break;
    }
    int iStatus = ferror(fFile);
    fclose(fFile);
    if(iStatus)
    {
        const char *sError = strerror(errno);
        return luaL_error(L, "cannot read %s: %s", sFilename, sError);
    }

    // Check file
    char *sFile = reinterpret_cast<char*>(lua_touserdata(L, lua_upvalueindex(1)));
    sFile[iBufferUsed] = 0;
    if(sFile[0] == '#')
    {
        do
        {
          ++sFile;
          --iBufferUsed;
        } while(sFile[0] != 0 && sFile[0] != '\r' && sFile[0] != '\n');
    }
    if(sFile[0] == LUA_SIGNATURE[0])
    {
        return luaL_error(L, "cannot load %s: compiled files not permitted", sFilename);
    }

    // Load and do file
    lua_pushliteral(L, "@");
    lua_pushvalue(L, 1);
    lua_concat(L, 2);
    if(luaL_loadbuffer(L, sFile, iBufferUsed, lua_tostring(L, -1)) != 0)
        return lua_error(L);
    lua_remove(L, -2);
    int iBufferCopyIndex = lua_gettop(L);
    memcpy(lua_newuserdata(L, iBufferUsed + 1), sFile, iBufferUsed + 1);
    lua_insert(L, -2);
    lua_call(L, 0, LUA_MULTRET);
    sFile = reinterpret_cast<char*>(lua_touserdata(L, lua_upvalueindex(1)));
    memcpy(sFile, lua_touserdata(L, iBufferCopyIndex), iBufferUsed + 1);
    lua_remove(L, iBufferCopyIndex);

    // Extract persistable functions
    const char *sPosition = sFile;
    while(true)
    {
        sPosition = strstr(sPosition, "--[[persistable:");
        if(!sPosition)
            break;
        sPosition += 16;
        const char *sNameEnd = strstr(sPosition, "]]");
        if(sNameEnd)
        {
            int iLineNumber = CalculateLineNumber(sFile, sNameEnd);
            const char *sFunctionArgs = strchr(sNameEnd + 2, '(');
            const char *sFunctionEnd = FindFunctionEnd(L, sFunctionArgs);
            if((sNameEnd - sPosition) == 1 && *sPosition == ':')
            {
                // --[[persistable::]] means take the existing name of the function
                sPosition = strstr(sNameEnd, "function") + 8;
                sPosition += strspn(sPosition, " \t");
                sNameEnd = sFunctionArgs;
                while(sNameEnd[-1] == ' ')
                    --sNameEnd;
            }
            if(iLineNumber != -1 && sFunctionArgs && sFunctionEnd)
            {
                // Save <filename>:<line> => <name>
                lua_pushfstring(L, "%s:%d", sFilename, iLineNumber);
                lua_pushvalue(L, -1);
                lua_gettable(L, lua_upvalueindex(2));
                if(lua_isnil(L, -1))
                {
                    lua_pop(L, 1);
                    lua_pushlstring(L, sPosition, sNameEnd - sPosition);
                    lua_settable(L, lua_upvalueindex(2));
                }
                else
                {
                    return luaL_error(L, "Multiple persistable functions defin"
                        "ed on the same line (%s:%d)", sFilename, iLineNumber);
                }

                // Save <name> => <filename>
                lua_pushlstring(L, sPosition, sNameEnd - sPosition);
                lua_pushvalue(L, -1);
                lua_gettable(L, lua_upvalueindex(3));
                if(lua_isnil(L, -1))
                {
                    lua_pop(L, 1);
                    lua_pushvalue(L, 1);
                    lua_settable(L, lua_upvalueindex(3));
                }
                else
                {
                    return luaL_error(L, "Persistable function name \'%s\' is"
                        " not unique (defined in both %s and %s)",
                        lua_tostring(L, -2), lua_tostring(L, -1), sFilename);
                }

                // Save <name> => <code>
                lua_pushlstring(L, sPosition, sNameEnd - sPosition);
                lua_pushliteral(L, "\n");
                lua_getfield(L, -1, "rep");
                lua_insert(L, -2);
                lua_pushinteger(L, iLineNumber - 1);
                lua_call(L, 2, 1);
                lua_pushliteral(L, "function");
                lua_pushlstring(L, sFunctionArgs, sFunctionEnd - sFunctionArgs);
                lua_concat(L, 3);
                lua_settable(L, lua_upvalueindex(4));
            }
        }
    }

    // Finish
    return lua_gettop(L) - 1;
}