Advertisement

Dynamic import of native functions

Started by July 26, 2020 11:27 AM
3 comments, last by WitchLord 3 years, 9 months ago

Hi, guys!

I want to use AngelScript in my Windows kernelmode framework to get easy and convenient access to native system functions.

What I really need is dynamic functions importing that are absent in compile-time.
For example, I got a raw native address and want to call it using funcdefs (or something else if it possible in other ways).

How could I achieve this?

For example I have an attempt with something like this:

uint64_t getKernelProcAddress(const std::string& str)
{
    ANSI_STRING ansi{};
    RtlInitAnsiString(&ansi, str.c_str());
    UNICODE_STRING name{};
    NTSTATUS status = RtlAnsiStringToUnicodeString(&name, &ansi, TRUE);
    if (!NT_SUCCESS(status))
    {
        return 0;
    }

    void* addr = MmGetSystemRoutineAddress(&name);
    RtlFreeUnicodeString(&name);
    return reinterpret_cast<uint64_t>(addr);
}

CScriptAny* registerNative(uint64_t engine, const std::string& prototype, uint64_t address)
{
    asIScriptEngine* e = reinterpret_cast<asIScriptEngine*>(engine);
    int res = e->RegisterGlobalFunction(prototype.c_str(), asFUNCTION(address), asCALL_STDCALL);
    assert(res >= 0);

    asIScriptFunction* func = mod->GetGlobalFunctionByDecl(prototype.c_str());
    CScriptAny* any = new CScriptAny(e);
    any->Store(func, func->GetTypeId());
    // ^ Asserts here with message 'index < length' in as_scriptengine.cpp:4449 (WIP-2.35 2020/07/17)

    return any;
}

void test()
{
    ...

    res = engine->RegisterGlobalFunction("any @registerNative(uint64, const string &in, uint64)", asFUNCTION(registerNative), asCALL_STDCALL);
    assert(res >= 0);

    res = engine->RegisterGlobalFunction("uint64 getKernelProcAddress(const string &in)", asFUNCTION(getKernelProcAddress), asCALL_STDCALL);
    assert(res >= 0);

    const char script[] =
        "funcdef uint64 FnGetEprocess();\n"
        "\n"
        "uint64 main(uint64 engine)\n"
        "{\n"
        "    uint64 addr = getKernelProcAddress('PsGetCurrentProcess');\n"
        "    any func = registerNative(engine, 'uint64 PsGetCurrentProcess()', addr);\n"
        "    FnGetEprocess @getEprocess;\n"
        "    func.retrieve(@getEprocess);\n"
        "    uint64 eprocess = getEprocess();\n"
        "    return eprocess;\n"
        "}\n";
        
    ... Running this script ...
}

So, is it possible to do something like this?

If nothing changed in that area in past few years, you could register absent functions as usual but make them point to some placeholders doing nothing. When time comes, replace function address stored by AngelScript with real function address.

It's been too long to provide full working example but take a look at `asCScriptFunction::sysFuncIntf::func` (as_callfunc.h). I remember messing with that when disabling / providing new implementation of already registered function(s), maybe that can put you on right track.

#include <as_callfunc.h>
#include <as_scriptengine.h>
#include <as_scriptfunction.h>

uint SScript::GetFunctionAddress( asIScriptEngine* engine, const char* decl )
{
	asCScriptFunction* func = (asCScriptFunction*)engine->GetGlobalFunctionByDecl( decl );
	if( !func )
		return( 0 );

	uint result = (uint)(func->sysFuncIntf->func);

	return result;
}

Games are meant to be created, not played...

Advertisement

@hoshimin you can do what you want.

You just made a small error when storing the function handle in the CScriptAny. You need to send in the pointer to the pointer of the script function.

    any->Store(&func, func->GetTypeId() | asTYPEID_OBJHANDLE);

I'll check on the assert failure, though, that is probably a bug in AngelScript.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I've finally fixed the assert failure that happened when CreateScriptObjectCopy was called with an asITypeInfo for a script function.

This fix is available in rev 2703.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement