android kernel syscall table hook - android

I am using android 4.2.2(Jelly Been) with linux-kernel 3.0.31 source code. I am trying to hook open system call but i don't know that how to change a page from read-only to writable given an address because sys_call_table is read-only.
I have do it successfully on linux Ubuntu12.04 3.2.32 with lookup_address() function below.
int make_rw(unsigned long address)
{
unsigned int level;
pte_t *pte = lookup_address(address, &level);
if(pte->pte &~ _PAGE_RW)
pte->pte |= _PAGE_RW;
return 0;
}
but unfortunately this function is for x86 not for arm. I don't know how to do it on arm-arch
another way: based on write protect register
#define CR0_WP 0x10000 //Write Protect Bit (CR0:16)
unsigned long cr0;
cr0 = read_cr0();
write_cr0(cr0 & ~CR0_WP);/* remove write protection*/
hookfunc(){...};
write_cr0(cr0);/* set write protection*/
but i do not know the relative register on arm-arch
Does there anyone have solved this problem? waiting for answer online!

Related

How to load external .so in Android 10+

I'm trying to load a external library for certain app when it be launched (on Platform Android 12).
And the external library will hook some function in it initialize function and then can help me get app's info.
The point is ,i can't load my library correctly.
I know Android 8+ dont allow load system lib by app,and dlopen will do return address check as blow
__attribute__((__weak__))
void* dlopen(const char* filename, int flag) {
const void* caller_addr = __builtin_return_address(0);
return __loader_dlopen(filename, flag, caller_addr);
}
You should make the caller_addr be a system lib address(or some like this?).
So,I used PLT hook tools to hook __loader_dlopen() in libdl.so,and do external load for target app like this to pass validation.
void* my_fake__loader_dlopen(const char* filename,int flag,void* caller_addr)
{
if(in_target_app)
{
void* res = __loader_dlopen(target_so_path,flag,caller_addr)//res always return NULL
}
return __loader_dlopen(filename,flag,caller_addr);
}
But res always return NULL,i cant load my lib correctly.
which of the above steps went wrong ? or is there another way to achieve my goal?
PS:
I can make sure:
put my lib in /system/lib64/
hook function correctly

How to get a full android app UID programmatically?

Edit 10 Apr 2020
I may have misnamed what we are looking for. It may actually be the linux user name of the installed app, rather than its UID. So how should we get that programmatically?
Original question below
When we use adb shell ps even on a non rooted android device, it returns process info where the UID comes in the form u0_xxxx where x represents some arbitrary digits in hex (except for system/root processes).
For example
u0_a464 31481 894 5015336 69200 0 0 S com.example.app_uid_checker
In this example app_uid_checker is my app in user space. When trying to obtain the UID programmatically, though, I get 10464 (the decimal representation of a464), and without the u0 prefix.
I tried
package manager's getApplicationInfo()
activity manager's getAllRunningProcess()
android.os.Process.myUid()
(following suggestions in this post on SO. They all return 10464. How can I get the "full" UID? (for want of a better term, I'm not sure what the u0_a464 version of the UID should be called, as compared to the 10464 version)).
Even if we can programmatically use adb shell ps I think it may not be a good way, as adb needs developer mode to be enabled.
You need to use the geteuid(2) and getpwuid(3) to retrieve the data, as the JVM does not expose it.
extern "C" JNIEXPORT jstring JNICALL Java_com_example_GetUser_getUser(JNIEnv* env) {
uid_t uid = geteuid();
struct passwd *user;
if (uid == -1)
return NULL;
user = getpwuid(uid);
return env->NewStringUTF(user->pw_name);
}
Full working project: https://gitlab.com/hackintosh5/getuser

Receiving socket information from netfilter NF_INET_PRE_ROUTING hook function in linux kernel

I wrote a netfilter hook function for incoming packets in linux kernel. Is there a way to get the receiving socket information from the hook function. The code is
register() {
hk.hook = hookfunction;
hk.hooknum = NF_INET_PRE_ROUTING;
hk.pf = PF_INET;
hk.priority = NF_IP_PRI_LAST;
}
static unsigned int hookfunction (void *priv,struct sk_buff,const struct nf_hook_state *state) {
if (skb->sk) {
printk("%d", skb->sk->sk_mark);
}
}
Lets assume I have a udp socket open at port 15000 and a udp packet arrives at port 15000. In the above written hook function how can I access the struct sock of the udp socket opened at port 15000. With the above code, the control doesnot pass the if(skb->sk) condition as if skb->sk is null. Can you please suggest me a way to get the struct sock of the socket or should I have to put the hook in some other position like NF_INET_LOCAL_IN,. I am also confused about the difference between NF_INET_XX_XX and NF_IP_XX_XX.
The kernel uses __inet_lookup_skb() internally to get sk from skb, which calls skb_steal_sock() first to check if skb->sk is NULL, if that is the case, it then calls __inet_lookup() to lookup sk.
However you might need to tweak the kernel a little bit because __inet_lookup_skb symbol is not exported and can't be called directly.
Some references from kernel source:
1 2 3
Regarding NF_INET_XX if you are talking about NF_IP_PRE_ROUTING and NF_INET_PRE_ROUTING I believe NF_IP_PRE_ROUTING is obsolete in recent kernel, as far as I know 4.4 has replaced it with NF_INET_PRE_ROUTING.
Hope that helps.

device oopswhen module is removed

When I use LKM to hook syscall about Android Kernel,I get something wrong
but I'm not good at Linux kernel debug,and I want to know how to deal with this problem.The similar problem told me the reason is read is blocked but module has been rmmod,I want to know how to solve this problem.
The reason is I want to monitor the apk's behavior.so I choose hook Linux kernel 3.4.67(goldfish) and with Android 4.4.4 code complied
Here is My code,when I insmod the module,it really get the action about read sth. But when I rommd the module ,the emulator direct get oops,and I finally find the reason is in my sys_read() hook,because when I hook syscall open ,it's okay.
#include <linux/kernel.h>
#include <linux/module.h>
#include<linux/init.h>
#include <linux/unistd.h>
#include <linux/semaphore.h>
#include <linux/moduleparam.h>
#include <asm/cacheflush.h>
#include<linux/delay.h>
#include<linux/file.h>
#include<linux/fs.h>
#include<linux/dirent.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SafeCode han");
void ** sys_call_table;
asmlinkage int (*original_call_read) (unsigned int, char*, int);
asmlinkage int hack_sys_read(unsigned int fd, char * buf, int count){
if(fd == 0 && count == 1)
{
printk("something is read aha %s\n", buf);
}
return original_call_read(fd,buf count);
}
int init_module()
{
//this is my sys_call_table address which found in System.map
sys_call_table =(void*)0xc000d984;
printk(KERN_ALERT "testhahaha\n");
original_call_read = sys_call_table[__NR_read];
sys_call_table[__NR_read] = hack_sys_read;
return 0;
}
/*when I need to rommd my module ,the devices oops..*/
void cleanup_module()
{
sys_call_table[__NR_read]=original_call_read;
//sys_call_table[__NR_open]=original_call_open;
}
so ,Plz help me~ thanks~,I want to know the depth reason and the solution
It is unsafe to revert previous value of the syscall's pointer and unload the module, contained replacement code: some process may use your syscall function at this moment, and it will be very upset when its code is gone off. As far as I know, there is no protection against that.
Syscalls are not intended to be changed by kernel modules. Either patch kernel code itself, or do not touch syscalls at all and use some sort of hooks, e.g. kprobes.

Alternative to /proc/PID/exe symlink for retrieving another processes full path via PID

I'm looking for a alternative method to reading the /proc/PID/exe symbolic link in which to obtain the full path of a process in Android/Linux.
The reason being is that on Android, /proc/PID/exe for any process other than your own or 'self' seem to have restricted (permission denied) access.
I have looked into the following as well - they are readable, but don't seem to work:
/proc/PID/cmdline: Rarely contains the full path
/proc/PID/stat: Contains only the executable name (no path)
Failing code due to permission denied:
#include <unistd.h>
// ...
char buf[2048];
// "/proc/1234/exe" is of course replaced with a proper PID
ssizet_t len = readlink("/proc/1234/exe", buf, sizeof(buf) - 1);
if(-1 != len) {
buf[len] = '\0';
// buf should contain full path
} else {
// this path always reached for PID's other than my own or
// /proc/self/exe
}
There has to be a alternative method? In Windows, there is of course GetModuleFileNameEx, QueryFullProcessImageName(), etc.
There's other places where you can obtain the information - eg /proc/<pid>/maps - but if you're not allowed to access /proc/<pid>/exe then you aren't allowed to access those, either.
There's no end-run around it - it's a consequence of Android's security model, where each app is given its own UID.

Categories

Resources