Skip to content

Instantly share code, notes, and snippets.

@yath
Created October 17, 2021 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yath/bf5341005203a199f11c701748076f26 to your computer and use it in GitHub Desktop.
Save yath/bf5341005203a199f11c701748076f26 to your computer and use it in GitHub Desktop.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/kallsyms.h>
typedef unsigned long word;
#define FAR_JMP 0xe51ff004 // ldr pc, [pc, #-4]
enum {
TI_BRANCH_HOOK_1 = 0, // FAR_JMP
TI_BRANCH_HOOK_2, // addr of hook
TI_ORIG_INSN_1, // overwritten first word of f
TI_ORIG_INSN_2, // overwritten second word of f
TI_CALL_ORIG_1, // FAR_JMP
TI_CALL_ORIG_2, // addr of f+8
TI_CALL_MAX,
} trampile_instruction_t;
static int hook_fun(word *f, void *hook, void **orig_fun) {
word *trampoline;
int i;
word branch_f[2];
trampoline = kcalloc(TI_CALL_MAX, sizeof(word), GFP_KERNEL);
trampoline[TI_BRANCH_HOOK_1] = FAR_JMP;
trampoline[TI_BRANCH_HOOK_2] = hook;
trampoline[TI_ORIG_INSN_1] = f[0];
trampoline[TI_ORIG_INSN_2] = f[1];
trampoline[TI_CALL_ORIG_1] = FAR_JMP;
trampoline[TI_CALL_ORIG_2] = f+2;
*orig_fun = &trampoline[TI_ORIG_INSN_1];
f[0] = FAR_JMP;
f[1] = trampoline;
printk(KERN_INFO "hook_fun(f=%pS (%px), hook=%pS (%px)), trampoline is at %px\n", f, f, hook, hook, trampoline);
for (i = 0; i < TI_CALL_MAX; i++)
printk(KERN_INFO " trampoline[%d] = %lx\n", i, trampoline[i]);
for (i = 0; i < 2; i++)
printk(KERN_INFO " f[%d]: %lx\n", i, f[i]);
return 0;
}
int (*orig_MTAUD_SetChannelVolume)(int, int, int);
int my_MTAUD_SetChannelVolume(int decoder, int channel, int value) {
printk(KERN_INFO "my_MTAUD_SetChannelVolume(%d, %d, %d)\n", decoder, channel, value);
orig_MTAUD_SetChannelVolume(0, 6, value);
orig_MTAUD_SetChannelVolume(0, 7, value);
return orig_MTAUD_SetChannelVolume(decoder, channel, value);
}
int init_module(void)
{
void *p;
printk(KERN_INFO "Init.\n");
p = kallsyms_lookup_name("_MTAUD_SetChannelVolume");
if (!p) {
printk(KERN_ERR "can't find symbol\n");
return -ENOENT;
}
hook_fun((word *)p, my_MTAUD_SetChannelVolume, &orig_MTAUD_SetChannelVolume);
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Unload.\n");
}
MODULE_LICENSE("GPL");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment