[Q] Need help hijacking/hooking/wrapping kernel function - Android Q&A, Help & Troubleshooting

I've made some modifications to drivers/usb/otg/msm_otg.c in order to support usb host mode for the Nexus 4: http://forum.xda-developers.com/showthread.php?t=2181820
So far, I've been building off Franco's sources, since I was using his kernel anyway. But this has its problems. I'm not looking to have to constantly keep up with Franco's nightlies. A good amount of posts from people are asking if I could compile a different kernel with the otg modifications, or if they could flash a different kernel on top. Franco's been getting requests to implement the modifications, and I didn't mean to put any onus on him.
I've been trying to do some research on creating a kernel module that could somehow hijack/hook/wrap the static functions I've made changes to in msm_otg.c. This is all way, way over my head though, and I could really use some help here. I've done some reading so far, but it hasn't gotten me anywhere. I got some good help on IRC, but am stuck again.
To get things rolling, I've manually found the address from /proc/kallsyms of static function msm_chg_detect_work to be 0xc03b4950. I'm trying to make a jump from here to my own function. I was provided make_jump_op for this purpose, although I have no understanding of how it works. Here is more or less what I've got so far (relevant bits..):
Code:
// max distance: 0x02000000
unsigned int make_jump_op(unsigned int src, unsigned int dst) {
unsigned int o;
int distance;
distance = (int)( ((long long)dst) - (((long long)src) + 8) );
if (distance > 32*1024*1024 || distance < -32*1024*1024) {
printk(KERN_ERR "distance too big!\n");
return 0; // crash, BOOOOM!
}
distance = distance / 4; // read: ">>2"
o = *((unsigned int *)(&distance)); // is there a proper way to do this, too?
o = (o & 0x00ffffff) + 0xea000000;
return o;
}
static void msm_chg_detect_work_MOD(struct work_struct *w) {
printk(KERN_INFO "TEST\n");
}
static int ziddey_otg_init(void) {
unsigned int *origcall;
printk(KERN_INFO "Loading kernel module '%s'\n", MODULE_NAME);
// 0xc03b4950: msm_chg_detect_work
origcall = (unsigned int *) 0xc03b4950;
preempt_disable();
*origcall = make_jump_op(0xc03b4950, (unsigned int)(void*)msm_chg_detect_work_MOD);
preempt_enable();
printk(KERN_INFO "Loaded kernel module '%s'\n", MODULE_NAME);
return 0;
}
Can anyone make sense of this? I get an Oops error and kernel panic.
Thank you
Code:
$ grep msm_chg_detect_work /proc/kallsyms
c03b4950 t msm_chg_detect_work

Related

Need help troubleshooting my code.

Ok so for these last three days i have been trying to get into the android game. I did the hello android tutorial and yea. that was boring lol, so i decided to try and create a program to temporarily fix the keyboard backlight issue being experienced by some ICS port users. i have only part of the code done but it does not execute at all. I am not sure whats the problem. I have writted additional pieces to this code but have not put them in the program as i want to figure out why it doesnt run before i add more and then clean it up.
Code:
package com.dri94.led;
import java.util.*;
import java.io.*;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class LEDLightActivity extends Activity {
/** Called when the activity is first created. */
@SuppressWarnings("null")
@Override
public void onCreate(Bundle savedInstanceState) {
final int SDK_INT;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Scanner input = new Scanner(System.in);
DataOutputStream os = null;
TextView tv = new TextView(this);
tv.setText("Enter 'y' to turn on keyboard light or 'n' to turn it off");
String yOrN = input.next();
if (yOrN == "y") {
tv.setText("Enter SDK number 7 for GB devices or 14 for ICS devices. No other devices are supported at this time");
SDK_INT = input.nextInt();
if (SDK_INT == '7') {
try {
os.writeBytes("echo 255 > /sys/class/leds/keyboard-backlight/brightness\n"
+ "chmod 444 /sys/class/leds/keyboard-backlight/brightness\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
try {
os.writeBytes("echo 255 > /sys/class/leds/kpd_backlight_en\n"
+ "chmod 444 /sys/class/leds/kpd_backlight_en\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Any logcat output? I don't have ICS so those paths aren't available on my device, but similar paths are symlinks and directories. Does your app have write permissions to kpd_backlight_en (or whatever the symlink points to)?
You have a lot of problems there, lets point some of them out,
Code:
DataOutputStream os = null;
Youre initializating your outputStream as null, wich is a problem consideering you use it for writing a file. Also there are so many easier ways to write files, for example, I propose this simple writing method
Code:
public static void WriteFile(String text, String file) {
try{
FileWriter fstream = new FileWriter(file);
BufferedWriter out = new BufferedWriter(fstream);
out.write(text);
out.close();
}catch (Exception e){
//Deal exception ;D
}
}
simple code usage will be then
Code:
WriteFile("255", "/sys/class/leds/keyboard-backlight/brightness");
Second error I found, comparing strings with "==", this
Code:
if (yOrN == "y")
is wrong, you should try with
Code:
if (yOrN.equals("y")) {
Another thing i dont understand is this
Code:
final int SDK_INT;
Why do you declare a variable as final, if you are gonna assign some value later, right here
Code:
SDK_INT = input.nextInt();
Last thing I found is also comparing an integer with string? I dont understand what you do there
Code:
if (SDK_INT == '7')
Also your way to manage user inputs would be better with a simple button (or toggleButton) for turn on/off lights, or even use SensorEventListener.
I hope I have helped you in some , just tell me if you need something. Good luck!
How should i initialize it? And thank you alot. Ima play with my code tomorrow. The last one though is comparing it with a character value. but this post helped alot. I appreciate it... Especially cause i made soooo many beginner mistakes. My professor would be disappointed
Sent from my XT862 using T
Questions or Problems Should Not Be Posted in the Development Forum
Please Post in the Correct Forums
Moving to Q&A
thanks i wasnt sure where to post this! ill remember that from now on

[Q] {Q} How can I unpack Boot.img

I want to unpack a Boot.img file to have a look at the Kernel coding. I have been at Google-ing this for about an hour and need some help. I am using windows but could use Ubuntu if need be.
Help would be much appreciated!!!
first of all by unpacking boot.img you won't see actual kernel coding.. it will merely 0.05% give you some idea about coding stuff here..
ketut released some tools which you can find in his kernel thread [not cf-root thread]..
if you wan't code then you will have to download kernel sources from github or samsung site.. and play at own risks
Okay, it looks like I am going to install Ubuntu. I was just hoping there was some way to do it within Windows without running a V.M. or Dual boot.
yes there are two ways of installing it with wubi installer to install within windows.. and one creating separate partition of ext4 to dual boot..
wubi installer seems to be what you are looking for
I am currently looking here https://github.com/ilarrain/kernel_galaxyace/blob/gingerbread/arch/arm/mach-msm/acpuclock.c and trying to understand the references to the frequency table. I want to understand why the table goes to 1036800 (like the CM7 Kernel) but is limited to 902400. It would help if I had the CM7 Kernel source for reference. Do you know where that can be found?
I am pretty sure this is what I need to be looking at:
#ifdef CONFIG_CPU_FREQ_MSM
static struct cpufreq_frequency_table freq_table[20];
static void __init cpufreq_table_init(void)
{
unsigned int i;
unsigned int freq_cnt = 0;
/* Construct the freq_table table from acpu_freq_tbl since the
* freq_table values need to match frequencies specified in
* acpu_freq_tbl and acpu_freq_tbl needs to be fixed up during init.
*/
for (i = 0; acpu_freq_tbl.a11clk_khz != 0
&& freq_cnt < ARRAY_SIZE(freq_table)-1; i++) {
if (acpu_freq_tbl.use_for_scaling) {
freq_table[freq_cnt].index = freq_cnt;
freq_table[freq_cnt].frequency
= acpu_freq_tbl.a11clk_khz;
freq_cnt++;
}
}
/* freq_table not big enough to store all usable freqs. */
BUG_ON(acpu_freq_tbl.a11clk_khz != 0);
freq_table[freq_cnt].index = freq_cnt;
freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
pr_info("%d scaling frequencies supported.\n", freq_cnt);
}
#endif
-SGA- said:
I am currently looking here https://github.com/ilarrain/kernel_galaxyace/blob/gingerbread/arch/arm/mach-msm/acpuclock.c and trying to understand the references to the frequency table. I want to understand why the table goes to 1036800 (like the CM7 Kernel) but is limited to 902400. It would help if I had the CM7 Kernel source for reference. Do you know where that can be found?
I am pretty sure this is what I need to be looking at:
#ifdef CONFIG_CPU_FREQ_MSM
static struct cpufreq_frequency_table freq_table[20];
static void __init cpufreq_table_init(void)
{
unsigned int i;
unsigned int freq_cnt = 0;
/* Construct the freq_table table from acpu_freq_tbl since the
* freq_table values need to match frequencies specified in
* acpu_freq_tbl and acpu_freq_tbl needs to be fixed up during init.
*/
for (i = 0; acpu_freq_tbl.a11clk_khz != 0
&& freq_cnt < ARRAY_SIZE(freq_table)-1; i++) {
if (acpu_freq_tbl.use_for_scaling) {
freq_table[freq_cnt].index = freq_cnt;
freq_table[freq_cnt].frequency
= acpu_freq_tbl.a11clk_khz;
freq_cnt++;
}
}
/* freq_table not big enough to store all usable freqs. */
BUG_ON(acpu_freq_tbl.a11clk_khz != 0);
freq_table[freq_cnt].index = freq_cnt;
freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
pr_info("%d scaling frequencies supported.\n", freq_cnt);
}
#endif
Click to expand...
Click to collapse
Why not cooper_initramfs ?
Herpderp Adreno + Tegra.
Well..For the history,To unpack boot.img,you need to use cygwin.Here is complete instruction on doing this thing freeyourandroid.com

Ping app

hey guys,
Building an app that runs a ping command at the moment and I can't quite get it to work. If I modify the command to something that isn't a terminal command then it'll output my error statement but i can't get it to display the ping output. any help would be awesome. I know my outputs for my error are bad but it's an easy way to determine what path it's outputting.
package com.mycompany.myapp;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
import java.io.*;
import java.lang.Process;
public class MainActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TextView Text = new TextView(this);
Runtime runtime = Runtime.getRuntime();
try
{
Process proc = runtime.getRuntime().exec("system/bin/ping 192.168.1.1");
BufferedReader in = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
String line = "null";
while ((line = in.readLine()) != null) {
Text.setText(in.readLine());
}
}
catch (Exception e)
{
String line="55";
Text.setText(line);
}
setContentView(Text);
}
}
Thanks for any help you guys can give me,
Adam
Hey,
Try using "system/bin/ping -c 1 192.168.1.1" instead.
And then add this line just after that:
Code:
proc.waitFor();
and while reading the output of the ping you might want to do it like this maybe?
Code:
String line = "";
String result = "";
while (line != null)
{
result = result + "\n" + line;
line = in.readLine();
}
Text.setText(result);
If you want to ping more than 1 packet I think it would be better to make a new thread and do proc.waitFor() in that thread. Then send a message using a handler to set the output of the ping to the TextView
k i have done that and that does make more sense but Im still getting a black screen on the output. i am testing on a Sony tab s and using AIDE (on the device) cause my eclipse is broken. this is how my code looks now,
package com.mycompany.myapp;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
import java.io.*;
import java.lang.Process;
public class MainActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TextView Text = new TextView(this);
Runtime runtime = Runtime.getRuntime();
try
{
Process proc = runtime.getRuntime().exec("system/bin/ping 192.168.1.1");
BufferedReader in = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
String line = "null";
while ((line = in.readLine()) != null) {
Text.setText(in.readLine());
}
}
catch (Exception e)
{
String line="55";
Text.setText(line);
}
setContentView(Text);
}
}
Is there anything else I could be missing??
Thanks,
Adam
Hey, I think you posted the same code again.
I am not sure if you can read the process stream before it is complete and ping does take a long time to complete. So your main thread is blocking on it and it doesn't get to executing the setContentView.
Thats why I think going for a seperate thread is a better option.
so it would be better to put the ping into a new class and call on it when i need it??
Not a seperate class, a seperate thread to be more specific.
Even if you do put the ping code in a seperate class' method and call that method in onCreate it will still run on the your applications main thread.
What I was trying to say is something along the lines of the following code:
Code:
private TextView textView;
private Process process;
private Handler handler;
private Thread pingThread;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
textView = new TextView(this);
textView.setText("Pinging...");
setContentView(textView);
try
{
process = Runtime.getRuntime().exec("system/bin/ping -c 5 192.168.1.1");
handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
String result = "";
while(line != null)
{
result = result + "\n" + line;
line = reader.readLine();
}
reader.close();
textView.setText(result);
}
catch(Exception e)
{
e.printStackTrace();
textView.setText("Error");
}
}
};
pingThread = new Thread()
{
@Override
public void run()
{
try
{
process.waitFor();
}
catch(Exception e)
{
e.printStackTrace();
}
handler.sendEmptyMessage(0);
}
};
pingThread.start();
} catch (Exception e)
{
e.printStackTrace();
}
}
I am not sure if this is exactly how you want your app to behave. There might be a better way of doing what you want than what I have suggested but I tested the above code and it works for me.
thats wicked, basically what want my program to do is to run a ping command through a usb to rj45 adapter. at the moment I just need it to do the ping command through wifi and once that was working I was going to set it up to go through usb.
I wonder if there's something I'm doing wrong like I'm build the apk in AIDE on the tablet or something, cause I'm still getting a black screen when booting the app.
If I error the code up a bit, Like put "system/bin/pi ....." instead I do get pinging on the app but no error output and if the code is fine then nothing displays
That is very strange :S.
If you use the incorrect command it works fine but when you use the correct command it doesn't?
Can you post your code? or provide more details if possible?
the code is just the code you posted cause I thought if a I could get it working with that code then modify it to what it needs to do, when the command is incorrect it displays "ping....." but doesn't display an error, I'm going to install eclipse and build the package with that and see how it goes. did you test on a tablet and what did you use to deploy the package?
Adz117 said:
the code is just the code you posted cause I thought if a I could get it working with that code then modify it to what it needs to do, when the command is incorrect it displays "ping....." but doesn't display an error, I'm going to install eclipse and build the package with that and see how it goes. did you test on a tablet and what did you use to deploy the package?
Click to expand...
Click to collapse
I think i know whats happening. It isnt the Ide and using eclipse wont make much of a difference.
Are you usIng something like -c 5 in the ping command? Cause if you aren't i think ping is Going to take a really long time and all you'll see on the screen is "Pinging..."
Yea I have got that in the command, when the code is correct and working I dont get anything all I get is a black screen. Its when I error the command up a bit that I get pinging
Sent from my Sony Tablet S using XDA
hey guys,
just got eclipse running and tested it on an avd emulator and it runs perfect, so the question is what would cause it not to run on my tablet?
I have no idea! I don't have access to an Android Tablet, so I can't test it out! I tested it out on my phone too and it works just fine.
One thing I can suggest though is:
Put log statements throughout the program to signify where the the control has reached. Then run it on your tablet. That should shed some light on where the code is failing on your tablet.
tested it on my phone which is running 2.3 and it failed on there as well, "ping......" would pop up for about a second then disappear, also if I use a command like ls instead of ping on my tablet it will work perfectly fine so I'm guessing for some reason past android 2.1 it doesn't like the ping command. any ideas?
I tested it out on phone with 2.2. Did you try putting log statements and checking where it is failing.
You could also add breakpoints in your code and run it?

[q] [help] compiling recovery

Hello guys. i have been trying to compile cwm recovery for my phone. its using msm7627a board. am using the prebuilt kernel. i succeded compiling but when i flash its not displaying anything. i tried to see whats wrong , from the recovery log i found the frame buffer /dev/graphics is not available. Everything else works i can do a backup from ROM manager, even keystrokes work..adb shell works .. just the display not working..any ideas. ????
i also realise some other devices are not loaded.
how can i make the fb0 graphics loaded or any other fix.. ???
for those who have access to the source code ..
Code:
.................................................................................part of the concerned ui code..........................................................
int gr_init(void)
{
gglInit(&gr_context);
GGLContext *gl = gr_context;
gr_init_font();
gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC);
if (gr_vt_fd < 0) {
// This is non-fatal; post-Cupcake kernels don't have tty0.
perror("can't open /dev/tty0");
}
else
{
if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) {
// However, if we do open tty0, we expect the ioctl to work.
perror("failed KDSETMODE to KD_GRAPHICS on tty0");
gr_exit();
return -1;
}
}
gr_fb_fd = get_framebuffer(gr_framebuffer); // this is the call that fails because it tries opening /dev/graphics/fb0 which does then exists
if (gr_fb_fd < 0) {
gr_exit();
perror("cant get framebuffer");
return -1;
}
get_memory_surface(&gr_mem_surface);
fprintf(stderr, "framebuffer: fd %d (%d x %d)\n",
gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height);
/* start with 0 as front (displayed) and 1 as back (drawing) */
gr_active_fb = 0;
set_active_framebuffer(0);
gl->colorBuffer(gl, &gr_mem_surface);
gl->activeTexture(gl, 0);
gl->enable(gl, GGL_BLEND);
gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA);
gr_fb_blank(true);
gr_fb_blank(false);
return 0;
}
............................................................code,.........................................................

How to go about patching the kernel to get EHCI(USB 2.0) devices to behave like xHCI?

Basically, there has been an app ported to Android that allows even unrooted(stock) devices to deliver a bootrom exploit to the Nintendo Switch via USB-OTG and a USB cable (or C-to-C). USB 3.0 (xHCI) devices have no issues and deliver the exploit just fine. Apparently it is not even a USB 2.0 problem but rather how the EHCI performs, as certain USB 2.0 phones actually have the xHCI controller and can run the exploit just fine. What happens is that although it can detect the connected Switch in Tegra Recovery Mode, it just doesn't do anything and gives an error in the logs, "SUMBITURB failed".
On Linux desktop systems it is similar, but the exploit can still work with a kernel patch provided by a hacking group that discovered the exploit in the first place:
Code:
--- linux-4.14.27/drivers/usb/host/ehci-hcd.c.old 2018-04-17 18:00:00.000000000 +0000
+++ linux-4.14.27/drivers/usb/host/ehci-hcd.c 2018-04-17 18:00:00.000000000 +0000
@@ -873,14 +873,6 @@
INIT_LIST_HEAD (&qtd_list);
switch (usb_pipetype (urb->pipe)) {
- case PIPE_CONTROL:
- /* qh_completions() code doesn't handle all the fault cases
- * in multi-TD control transfers. Even 1KB is rare anyway.
- */
- if (urb->transfer_buffer_length > (16 * 1024))
- return -EMSGSIZE;
- /* FALLTHROUGH */
- /* case PIPE_BULK: */
default:
if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
return -ENOMEM;
The author of the Android port had also written a Python "hotpatch" script for desktop Linux systems:
Code:
#!/usr/bin/env python3
import os
"""
Cursed Code.
This code literally patches your kernel memory, proceed at your own risk.
Tested on Ubuntu 17.10 and Arch, x86_64. Should work on other distros, maybe even other architectures!
Run fusee-launcher.py with the "--override-checks" argument.
If you'd rather patch your drivers properly:
https://github.com/fail0verflow/shofel2/blob/master/linux-ehci-enable-large-ctl-xfers.patch
"""
ksyms = {
line[2]: int(line[0], 16)
for line in
map(lambda l: l.strip().split(),
open("/proc/kallsyms", "r").readlines())}
print(hex(ksyms["ehci_urb_enqueue"]))
patch_c = """
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/pgtable.h>
static u32 ORIG_MAX = 16*1024;
static u32 NEW_MAX = 0x1000000;
/* borrowed from MUSL because I'm lazy AF */
static char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
{
uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
for (h+=3, k-=3; k; k--, hw = hw<<8 | *++h)
if (hw == nw) return (char *)h-3;
return 0;
}
static pte_t* (*lookup_addr)(unsigned long, unsigned int*) = (void *) PLACE2;
static void set_addr_rw(unsigned long addr) {
unsigned int level;
pte_t *pte = lookup_addr(addr, &level);
set_pte_atomic(pte, pte_mkwrite(*pte));
}
int init_module(void) {
void * ehci_urb_enqueue_start = (void *) PLACEHOLDER;
u32 * patch_addr;
printk(KERN_INFO "Patch module loaded\\n");
patch_addr = (u32 *) fourbyte_memmem(ehci_urb_enqueue_start, 0x400, (void *)&ORIG_MAX);
if (patch_addr == NULL) {
printk(KERN_INFO "Failed to find patch site :(\\n");
return -1;
}
printk(KERN_INFO "patch_addr: 0x%px\\n", patch_addr);
set_addr_rw((unsigned long)patch_addr);
*patch_addr = NEW_MAX;
printk(KERN_INFO "Patching done!\\n");
return -1;
}
""".replace("PLACEHOLDER", hex(ksyms["ehci_urb_enqueue"])).replace("PLACE2", hex(ksyms["lookup_address"]))
makefile = """
obj-m += patch.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
"""
with open("patch.c", "w") as patchfile:
patchfile.write(patch_c)
with open("Makefile", "w") as mf:
mf.write(makefile)
os.system("make")
print("About to insert patch module, 'Operation not permitted' means it probably worked, check dmesg output.")
os.system("insmod patch.ko")
I tried to see if running it in Termux would do anything but I got the following error:
Code:
0x0
Traceback (most recent call last):
File "ehci_patch.py", line 70, in <module>
" " ".replace("PLACEHOLDER", hex(ksyms["ehci_urb_enqueue"])).replace("PLACE2" hex(ksyms["lookup_address"]))
KeyError: 'lookup_address'
I know that script isn't meant for use on Android anyway but maybe it can lead to a solution. The author of it does not know how to go about it at this time either, but believes an entire recompile of the kernel would be necessary. I am hoping that something like a systemless Magisk module would be the easiest solution for users but do not know if that is possible. I am only guessing it might be possible to create a Magisk module because of audio drivers like VIPER4Android. If indeed a custom kernel is needed, does anyone know how to go about it? It could be difficult to implement for everyone because not everyone has a device where the source to the kernel is available, etc. I am willing, however, to test anything on my tablet which is USB 2.0 and gives the error in the app. Any advice for how to go about this will be greatly appreciated.
I feel ya man, i need this stuff too. NXLoader doesn't work on my Galaxy Grand Prime (G530T) and i really need it to Dx

Categories

Resources