GCC-ARM call function of binary from other one - gcc

I have a main binary and an app binary. Main binary is compiled with FreeRTOS and has access to HAL layer and thus uart.
App binary is loaded at runtime. Now from App binary I need to call a uart_print function of main binary to log the message from uart. Apart from this also I need to call other function of main binary from app binary.
I searched on web and found How to write dynamic loader for bare-metal arm-application which suggest implementing jump tables.
I have the following implementation:
jumptbl.h
typedef struct _MyAPI
{
void (*jumptbl_msg)(const char *msg);
} MyAPI;
In main binary I have instantiate the structure:
void PrintMsg(const char* msg)
{
HAL_UART_Transmit(&huart3, (uint8_t*)'\n', 1,10);
}
__attribute__ ((section (".jumptbl"))) MyAPI main_API =
{
&PrintMsg,
};
In linker script I create a section to be placed at address :0x20001F00
.jumptbl_block 0x2001F000:
{
KEEP(*(.jumptbl))
} > RAM
And then from app binary I call the PrintMsg function.
MyAPI *pAPI = (MyAPI*)(0x2001F000);
pAPI->jumptbl_msg("hello world");
But my program hardfaults when the jump function is called.
Also, I tried another approach. I got the address of PrintMsg using arm-none-eabi-nm and directly calling it, but again the program hard faulted.
typedef void (*t_funcPtr)(const char *);
t_funcPtr MyFunc = (t_funcPtr)0x08001af4;
MyFunc("hello world");
Please can you suggest how can I call function of one binary in section sec_x loaded at address x from another binary.

Related

Kernel Error while using memcpy in the kernel module to change the content of the buffer passed as argument to the exported function

I have two kernel modules where first module had one function exported and second module uses this function to read spi data. sample program is given below
Module-1:
int spi_fun(uint8_t *tx_buf, uint8_t *rx_buf,int len)
{
spi_sync_txrx(tx_buf,rx_buf,len);
}
Module-2:
void dummy_fun()
{
uint8_t tx[4]={0};
uint8_t rx[4]={0};
spi_fun(tx,rx,4);
}
the above mentioned scenario is working fine. If I declare a local rx buffer(spi_data[4]) inside spi_fun(), and use memcpy to copy spi_data contents to the rx_buf, kernel is crashing with error as given below
New Module-2 fun:
Module-1:
int spi_fun(uint8_t *tx_buf, uint8_t *rx_buf,int len)
{
uint8_t spi_data[4];
spi_sync_txrx(tx_buf,spi_data,len);
memcpy(rx_buf, spi_data, len); //here error
}
Kernel Error:
Internal error: Accessing user space memory outside uaccess.h
routines: 96000045 [#1] PREEMPT SMP
I have used copy_from_user/copy_to_user functions, but i was getting target buffer as zeroes.
Does anyone experienced this issue???

Checking local filesystem fsid from osx kernel extension (kext)

I've got WA for checking what is the local fsid from within kext context, simply by reading predefined local file status.
static inline uint64_t get_fsid(const vfs_context_t ctx, const vnode_t vp) {
struct vnode_attr vap;
VATTR_INIT(&vap);
VATTR_WANTED(&vap, va_fsid);
vnode_getattr(vp, &vap, ctx);
return (uint64_t)vap.va_fsid;
}
another option is to calculate the fsid from user-space and pass this info to the driver (using getmntinfo)
However, I prefer getting this data from directly from the kernel space without relying on any files currently existed. is there any KPI to support this request ?
You can iterate over all mount points in the system using the function
int vfs_iterate(int, int (*)(struct mount *, void *), void *);
For each mount object, you can check its fsid using
struct vfsstatfs * vfs_statfs(mount_t);
vfsstatfs has an f_fsid field.
Both functions and the struct are declared and documented in <sys/mount.h>. The functions are exported in the BSD KPI.

How to convert a function address to a symbol

Let's say I have a program like this
// print-addresses.cpp
#include <stdio.h>
void foo() { }
void bar() { }
void moo() { }
int main(int argc, const char** argv) {
printf("%p\n", foo);
printf("%p\n", bar);
printf("%p\n", moo);
return 0;
}
It prints some numbers like
013510F0
013510A0
01351109
How do I convert those numbers back into the correct symbols? Effectively I'd like to be able to do this
print-addresses > address.txt
addresses-to-symbols < address.txt
And have it print
foo
bar
moo
I know this has something to do with the Debug Interface Access SDK but it's not entirely clear to me how I go from an address to a symbol.
This seems like exactly what you're looking for: Retrieving Symbol Information by Address. This uses DbgHelp.dll and relies on calling SymFromAddr. You have to do that (I think) from within the running application, or by reading in a minidump file.
You can also use the DIA, but the calling sequence is a bit more complicated. Call IDiaDataSource::loadDataForExe and IDiaDataSource::openSession to get an IDiaSession, then IDiaSession::getSymbolsByAddr to get IDiaEnumSymbolsByAddr. Then, IDiaEnumSymbolsByAddr::symbolByAddr will let you look up a symbol by address. There is also a way (shown in the example at the last link) to enumerate all symbols.
EDIT: This DIA sample application might be a good starting point for using DIA: http://msdn.microsoft.com/en-us/library/hd8h6f46%28v=vs.71%29.aspx . Particularly check out the parts using IDiaEnumSymbolsByAddr.
You could also parse the output of dumpbin, probably with /SYMBOLS or /DISASM option.
if you are in linux, you could try addr2line
addr2line addr -e execuablebin -f

Changing function reference in Mac OS Process at runtime

I need to change reference of a function in a Mac OS process at runtime to a custom function defined in my own custom dylib. I kept the new function signature same as the original.
For example I need to change "open" function to "myopen" function.
I tried processing __LINKEDIT segment to get the dynamic symbol table and string table.
I used following pointers,
1. the VMAddrress from __LINKEDIT segment,
2. mach_header and vmaddr_slide from the "_dyld_register_func_for_add_image" callback,
3. symoff and stroff from symtab_command.
But I am unable to get the symbol table and string table mentioned in the __LINKEDIT segment.
Can someone throw some light on this?
Thanks in advance.
If the function in question is a library function, and not statically compiled into the executable, you don't need to do any of that - you can use function interposing, instead. Specifically, add this to your library:
// The attribute creates a Mach-O Section in your library - q.v. libgmalloc.dylib for
// a nice example
static const interpose_t interposing_functions[] \
__attribute__ ((section("__DATA, __interpose"))) = {
{ (void *)my_open, (void *)open },
{ (void *)my_close, (void *)close }, // .. etc
};
int my_open(const char *path, int flags, mode_t mode)
{
int rc;
// Prolog - do something before open
rc = open(path, flags, mode); // call real open
// Epilog - record rc, etc..
return rc;
}
There are several excellent books on OS X internals which can provide you with samples, though apparently according to S.O site policies we can't link you to them. That said, the above code snippet should work. Bear in mind, that this won't work on calls to open performed by other dylibs (though there are more complicated ways to get that, as well)

Problems doing syscall hooking

I use the following module code to hooks syscall, (code credited to someone else, e.g., Linux Kernel: System call hooking example).
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
#include <asm/semaphore.h>
#include <asm/cacheflush.h>
void **sys_call_table;
asmlinkage int (*original_call) (const char*, int, int);
asmlinkage int our_sys_open(const char* file, int flags, int mode)
{
printk(KERN_ALERT "A file was opened\n");
return original_call(file, flags, mode);
}
int set_page_rw(long unsigned int _addr)
{
struct page *pg;
pgprot_t prot;
pg = virt_to_page(_addr);
prot.pgprot = VM_READ | VM_WRITE;
return change_page_attr(pg, 1, prot);
}
int init_module()
{
// sys_call_table address in System.map
sys_call_table = (void*)0xffffffff804a1ba0;
original_call = sys_call_table[1024];
set_page_rw(sys_call_table);
sys_call_table[1024] = our_sys_open;
return 0;
}
void cleanup_module()
{
// Restore the original call
sys_call_table[1024] = original_call;
}
When insmod the compiled .ko file, terminal throws "Killed". When looking into 'cat /proc/modules' file, I get the Loading status.
my_module 10512 1 - Loading 0xffffffff882e7000 (P)
As expected, I can not rmmod this module, as it complains its in use. The system is rebooted to get a clean-slate status.
Later on, after commenting two code lines in the above source sys_call_table[1024] = our_sys_open; and sys_call_table[1024] = original_call;, it can insmod successfully. More interestingly, when uncommenting these two lines (change back to the original code), the compiled module can be insmod successfully. I dont quite understand why this happens? And is there any way to successfully compile the code and insmod it directly?
I did all this on Redhat with linux kernel 2.6.24.6.
I think you should take a look to the kprobes API, which is well documented in Documentation/krpobes.txt. It gives you the ability to install handler on every address (e.g. syscall entry) so that you can do what you want. Added bonus is that your code would be more portable.
If you're only interested in tracing those syscalls you can use the audit subsystem, coding your own userland daemon which will be able to receive events on a NETLINK socket from the audit kthread. libaudit provides a simple API to register/read events.
If you do have a good reason with not using kprobes/audit, I would suggest that you check that the value you are trying to write to is not above the page that you set writable. A quick calculation shows that:
offset_in_sys_call_table * sizeof(*sys_call_table) = 1024 * 8 = 8192
which is two pages after the one you set writable if you are using 4K pages.

Resources