######################## Using *NativeFunction* s ######################## .. index:: NativeFunction Sometimes we may want to call a function defined in the program we're analyzing, or maybe we want to benefit from some of the imported functions avoiding to reimplement everything from scratch. Cause who wants to rewrite code anyways, right? This has a simple solution in the Frida world, we just need to create a ``NativeFunction`` object, to do this we'll need the following information: * The address of the function * The return type as :ref:`string ` * The type of the arguments as an array of :ref:`string ` In addition, depending on the binary we are working on we may need the following optional values: * :ref:`abi ` * scheduling * ``cooperative (Default)`` : Allows other JavaScript to keep running * ``exclusive`` : No other threads execute JavaScript code. It's faster but may cause deadlocks * exception * ``steal (Default)`` : If an exception is thrown during runtime, Frida will look in the stack and convert the excetion thrown into a JavaScript exception that we can catch as needed. * ``propagate`` : Let the application handle the exceptions through SEH. We can register an exception handler using ``Process.setExceptionHandler`` In our following example we'll hook to an ``nc`` process and spoof a message using the ``write`` import ____________________________ Getting the *NativeFunction* ____________________________ .. code-block:: JavaScript :linenos: /* According to the `man 2 write` linux documentation, the signature for the write function is: * * ssize_t write(int fd, const void *buf, size_t count); * * Which for us means, ['int', 'pointer', 'uint'] -> 'int' */ var write_fn = new NativeFunction(Module.findExportByName(null, 'write'), 'int', ['int', 'pointer', 'uint'] ); var my_str = "Hi, I'm spoofing a message"; my_message = Memory.allocUtf8String(my_str); console.log('Result:', write_fn(3, ptr(my_message), my_str.length)); ________________________ The *SystemFunction* API ________________________ .. index:: SystemFunction Some system calls provide detailed information in case of error that must be retrieved using ``errno`` or ``lastError``, depending on platform. For this particular cases an API called ``SystemFunction`` exists. The only difference between ``SystemFunction`` and ``NativeFunction`` is that the former returns an object with the return value in the field ``value`` and the last error number of the current thread in the field ``errno`` (UNIX) or ``lastError`` (Windows) .. code-block:: JavaScript :linenos: var write_fn = new SystemFunction(Module.findExportByName(null, 'write'), 'int', ['int', 'pointer', 'uint'] ); var my_str = "Hi, I'm spoofing a message"; my_message = Memory.allocUtf8String(my_str); var result = write_fn(10, ptr(my_message), my_str.length); //We use an invalid file descriptor here if(result.value < 0){ console.log('An error ocurred:', result.errno); } The previous snippet prints: An error ocurred: 9 Using the ``errno`` util (Package ``moreutils`` in most linux distros), we can check the error returned: .. code-block:: bash errno 9 EBADF 9 Bad file descriptor ___________________________ Creating a *NativeCallback* ___________________________ .. index:: NativeCallback .. _NativeCallback: At some point we'll be interested in adding new functionality to the program we are analyzing, to perform this task frida provides a convenient API to generate JavaScript functions that are executed in the context of the process/application we are instrumenting: .. code-block:: JavaScript :linenos: var my_callback = new NativeCallback( function(arg1, arg2){ console.log('In my new function with arguments:', arg1, arg2); return arg1==arg2; }, 'bool', ['int', 'int'], 'unix64' ); The ``NativeCallback`` API returns a ``NativePointer`` object, we'll see how to inject these objects into the process to use them as hooks in the next part of this guide. For now we'll see how to manually call the function we created. First of all, we need to turn the ``NativePointer`` object we got to a ``NativeFunction`` and then call it: .. code-block:: JavaScript :linenos: var my_function = new NativeFunction( my_callback, 'bool', ['int', 'int'], 'unix64' ); console.log(my_function(2,3));