china.com
主页
新闻
体育
游戏
文化
教育
健康
财经
科技
旅游
军事
娱乐
商贸
  科技动态 硬件广场 下载基地 网络教室 网络冲浪 科学博览 移动时代 手机上网 桌面壁纸 科技商情  


附录(源码)


Module insertion without native support

NAME : kinsmod.c

AUTHOR : Silvio Cesare

DESCRIPTION : This is a very nice program which allows us to insert LKMs on system with no native module support.

LINK : found it by a search on http://www.antisearch.com

/**********needed include file*/

#ifndef KMEM_H

#define KMEM_H

#include <linux/module.h>

#include <unistd.h>

#include <fcntl.h>

/*

these functions are anologous to standard file routines.

*/

#define kopen(mode) open("/dev/kmem", (mode))

#define kclose(kd) close((kd))

ssize_t kread(int kd, int pos, void *buf, size_t size);

ssize_t kwrite(int kd, int pos, void *buf, size_t size);

/*

ksyms initialization and cleanup

*/

int ksyms_init(const char *map);

void ksyms_cleanup(void);

/*

print the ksym table

*/

void ksyms_print(void);

/*

return the ksym of name 'name' or NULL if no symbol exists

*/

struct kernel_sym *ksyms_find(const char *name);

#endif

/**********KMEM functions*/

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdio.h>

#include <linux/module.h>

#include <linux/unistd.h>

#include "kmem.h"

struct ksymlist {

struct ksymlist* next;

struct kernel_sym ksym;

};

struct ksymlisthead {

struct ksymlist* next;

};

/*

the hash size must be an integral power of two

*/

#define KSYM_HASH_SIZE 512

struct ksymlisthead ksymhash[KSYM_HASH_SIZE];

/*

these functions are anologous to standard file routines.

*/

ssize_t kread(int kd, int pos, void *buf, size_t size)

{

int retval;

retval = lseek(kd, pos, SEEK_SET);

if (retval != pos) return retval;

return read(kd, buf, size);

}

ssize_t kwrite(int kd, int pos, void *buf, size_t size)

{

int retval;

retval = lseek(kd, pos, SEEK_SET);

if (retval != pos) return retval;

return write(kd, buf, size);

}

void ksyms_print(void)

{

int i;

for (i = 0; i < KSYM_HASH_SIZE; i++) {

struct ksymlist *head = (struct ksymlist *)&ksymhash[i];

struct ksymlist *current = ksymhash[i].next;

while (current != head) {

printf(

"name: %s addr: %lx\n",

current->ksym.name,

current->ksym.value

);

current = current->next;

}

}

}

void ksyms_cleanup(void)

{

int i;

for (i = 0; i < KSYM_HASH_SIZE; i++) {

struct ksymlist *head = (struct ksymlist *)&ksymhash[i];

struct ksymlist *current = head->next;

while (current != head) {

struct ksymlist *next = current->next;

free(current);

current = next;

}

}

}

int hash(const char *name)

{

unsigned long h;

const char *p;

for (h = 0, p = name; *p; h += (unsigned char)*p, p++);

return h & (KSYM_HASH_SIZE - 1);

}

int ksyminsert(struct kernel_sym *ksym)

{

struct ksymlist *node;

struct ksymlisthead *head;

node = (struct ksymlist *)malloc(sizeof(struct ksymlist));

if (node == NULL) return -1;

head = &ksymhash[hash(ksym->name)];

memcpy(&node->ksym, ksym, sizeof(*ksym));

node->next = (struct ksymlist *)head->next;

head->next = node;

return 0;

}

int ksyms_init(const char *map)

{

char s[512];

FILE *f;

int i;

for (i = 0; i < KSYM_HASH_SIZE; i++)

ksymhash[i].next = (struct ksymlist *)&ksymhash[i];

f = fopen(map, "r");

if (f == NULL) return -1;

while (fgets(s, sizeof(s), f) != NULL) {

struct kernel_sym ksym;

char *n, *p;

ksym.value = strtoul(s, &n, 16);

if (n == s || *n == 0) goto error;

p = n;

while (*p && isspace(*p)) ++p;

if (*p == 0 || p[1] == 0 || p[2] == 0) goto error;

p += 2;

n = p;

while (*p && !isspace(*p)) ++p;

if (*p) *p = 0;

strncpy(ksym.name, n, 60);

if (ksyminsert(&ksym) < 0) goto error;

}

fclose(f);

return 0;

error:

fclose(f);

ksyms_cleanup();

printf("--> %s\n", s);

return -1;

}

struct kernel_sym *ksyms_find(const char *name)

{

struct ksymlist *head = (struct ksymlist *)&ksymhash[hash(name)];

struct ksymlist *current = head->next;

while (current != head) {

if (!strncmp(current->ksym.name, name, 60))

return &current->ksym;

current = current->next;

}

return NULL;

}



/**********MAIN PROGRAM : kinsmod.c*/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <fcntl.h>

#include <elf.h>

#include <getopt.h>

#include "kmem.h"

static char system_map[] = "System.kmap";

static int error = 0;

static int run = 0;

static int force = 0;

struct _module {

Elf32_Ehdr ehdr;

Elf32_Shdr* shdr;

unsigned long maddr;

int maxlen;

int len;

int strtabidx;

char** section;

};

Elf32_Sym *local_sym_find(

Elf32_Sym *symtab, int n, char *strtab, const char *name

)

{

int i;

for (i = 0; i < n; i++) {

if (!strcmp(&strtab[symtab[i].st_name], name))

return &symtab[i];

}

return NULL;

}

Elf32_Sym *localall_sym_find(struct _module *module, const char *name)

{

char *strtab = module->section[module->strtabidx];

int i;

for (i = 0; i < module->ehdr.e_shnum; i++) {

Elf32_Shdr *shdr = &module->shdr[i];

if (shdr->sh_type == SHT_SYMTAB) {

Elf32_Sym *sym;

sym = local_sym_find(

(Elf32_Sym *)module->section[i],

shdr->sh_size/sizeof(Elf32_Sym),

strtab,

name

);

if (sym != NULL) return sym;

}

}

return NULL;

}

void check_module(struct _module *module, int fd)

{

Elf32_Ehdr *ehdr = &module->ehdr;

if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) {

perror("read");

exit(1);

}

/* ELF checks */

if (strncmp(ehdr->e_ident, ELFMAG, SELFMAG)) {

fprintf(stderr, "File not ELF\n");

exit(1);

}

if (ehdr->e_type != ET_REL) {

fprintf(stderr, "ELF type not ET_REL\n");

exit(1);

}

if (ehdr->e_machine != EM_386 && ehdr->e_machine != EM_486) {

fprintf(stderr, "ELF machine type not EM_386 or EM_486\n");

exit(1);

}

if (ehdr->e_version != EV_CURRENT) {

fprintf(stderr, "ELF version not current\n");

exit(1);

}

}

void load_section(char **p, int fd, Elf32_Shdr *shdr)

{

if (lseek(fd, shdr->sh_offset, SEEK_SET) < 0) {

perror("lseek");

exit(1);

}

*p = (char *)malloc(shdr->sh_size);

if (*p == NULL) {

perror("malloc");

exit(1);

}

if (read(fd, *p, shdr->sh_size) != shdr->sh_size) {

perror("read");

exit(1);

}

}

void load_module(struct _module *module, int fd)

{

Elf32_Ehdr *ehdr;

Elf32_Shdr *shdr;

char **sectionp;

int slen;

int i;

check_module(module, fd);

ehdr = &module->ehdr;

slen = sizeof(Elf32_Shdr)*ehdr->e_shnum;

module->shdr = (Elf32_Shdr *)malloc(slen);

if (module->shdr == NULL) {

perror("malloc");

exit(1);

}

module->section = (char **)malloc(sizeof(char **)*ehdr->e_shnum);

if (module->section == NULL) {

perror("malloc");

exit(1);

}

if (lseek(fd, ehdr->e_shoff, SEEK_SET) < 0) {

perror("lseek");

exit(1);

}

    if (read(fd, module->shdr, slen) != slen) {

        perror("read");

        exit(1);

    }

for (

i = 0, sectionp = module->section, shdr = module->shdr;

i < ehdr->e_shnum;

i++, sectionp++

) {

switch (shdr->sh_type) {

case SHT_NULL:

case SHT_NOTE:

case SHT_NOBITS:

break;

case SHT_STRTAB:

load_section(sectionp, fd, shdr);

if (i != ehdr->e_shstrndx)

module->strtabidx = i;

break;

case SHT_SYMTAB:

case SHT_PROGBITS:

case SHT_REL:

load_section(sectionp, fd, shdr);

break;

default:

fprintf(

stderr,

"No handler for section (type): %i\n",

shdr->sh_type

);

exit(1);

}

++shdr;

}

}

void relocate(struct _module *module, Elf32_Rel *rel, Elf32_Shdr *shdr)

{

Elf32_Sym *symtab = (Elf32_Sym *)module->section[shdr->sh_link];

Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];

Elf32_Addr addr;

Elf32_Shdr *targshdr = &module->shdr[shdr->sh_info];

Elf32_Addr dot = targshdr->sh_addr + rel->r_offset;

Elf32_Addr *loc = (Elf32_Addr *)(

module->section[shdr->sh_info] + rel->r_offset

);

char *name = &module->section[module->strtabidx][sym->st_name];

if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {

struct kernel_sym *ksym;

if (force) {

char novname[60];

int len;

len = strlen(name);

if (len > 10 && !strncmp(name + len - 10, "_R", 2)) {

strncpy(novname, name, len - 10);

novname[len - 10] = 0;

ksym = ksyms_find(novname);

} else

ksym = ksyms_find(name);

} else

ksym = ksyms_find(name);

if (ksym != NULL) {

addr = ksym->value;

#ifdef DEBUG

printf(

"Extern symbol is (%s:%lx)\n",

ksym->name,

(unsigned long)addr

);

#endif

goto next;

}

if (

sym->st_shndx == 0 ||

sym->st_shndx > module->ehdr.e_shnum

) {

fprintf(

stderr,

"ERROR: undefined symbol (%s)\n", name

);

++error;

return;

}

}

addr = sym->st_value + module->shdr[sym->st_shndx].sh_addr;

#ifdef DEBUG

printf("Symbol (%s:%lx) is local\n", name, (unsigned long)addr);

#endif

next:

if (targshdr->sh_type == SHT_SYMTAB) return;

if (targshdr->sh_type != SHT_PROGBITS) {

fprintf(

stderr,

"Rel not PROGBITS or SYMTAB (type: %i)\n",

targshdr->sh_type

);

exit(1);

}

switch (ELF32_R_TYPE(rel->r_info)) {

case R_386_NONE:

break;

case R_386_PLT32:

case R_386_PC32:

*loc -= dot; /* *loc += addr - dot */

case R_386_32:

*loc += addr;

break;

default:

fprintf(

stderr, "No handler for Relocation (type): %i",

ELF32_R_TYPE(rel->r_info)

);

exit(1);

}

}

void relocate_module(struct _module *module)

{

int i;

for (i = 0; i < module->ehdr.e_shnum; i++) {

if (module->shdr[i].sh_type == SHT_REL) {

int j;

Elf32_Rel *relp = (Elf32_Rel *)module->section[i];

for (

j = 0;

j < module->shdr[i].sh_size/sizeof(Elf32_Rel);

j++

) {

relocate(

module,

relp,

&module->shdr[i]

);

++relp;

}

}

}

}

void print_symaddr(struct _module *module, const char *symbol)

{

Elf32_Sym *sym;

sym = localall_sym_find(module, symbol);

if (sym == NULL) {

fprintf(stderr, "No symbol (%s)\n", symbol);

++error;

return;

}

printf(

"%s: 0x%lx\n",

symbol,

(unsigned long)module->shdr[sym->st_shndx].sh_addr

+ sym->st_value

);

}

void init_module(struct _module *module, unsigned long maddr)

{

int i;

unsigned long len = 0;

module->maddr = maddr;

for (i = 0; i < module->ehdr.e_shnum; i++) {

if (module->shdr[i].sh_type != SHT_PROGBITS) continue;

module->shdr[i].sh_addr = len + maddr;

len += module->shdr[i].sh_size;

}

module->len = len;

if (module->maxlen > 0 && module->len > module->maxlen) {

fprintf(

stderr,

"Module too large: (modsz: %i)\n",

module->len

);

exit(1);

}

printf("Module length: %i\n", module->len);

relocate_module(module);

print_symaddr(module, "init_module");

print_symaddr(module, "cleanup_module");

}

void do_module(struct _module *module, int fd)

{

int kd;

int i;

#ifdef DEBUG

for (i = 0; i < module->ehdr.e_shnum; i++) {

if (module->shdr[i].sh_type != SHT_PROGBITS) continue;

if (lseek(fd, module->shdr[i].sh_offset, SEEK_SET) < 0) {

perror("lseek");

exit(1);

}

if (

write(

fd, module->section[i], module->shdr[i].sh_size

) != module->shdr[i].sh_size

) {

perror("write");

exit(1);

}

}

#else

kd = open("/dev/kmem", O_RDWR);

if (kd < 0) {

perror("open");

exit(1);

}

if (lseek(kd, module->maddr, SEEK_SET) < 0) {

perror("lseek");

exit(1);

}

for (i = 0; i < module->ehdr.e_shnum; i++) {

if (module->shdr[i].sh_type != SHT_PROGBITS) continue;

if (

write(

kd, module->section[i], module->shdr[i].sh_size

) != module->shdr[i].sh_size

) {

perror("write");

exit(1);

}

}

close(kd);

#endif

}

int main(int argc, char *argv[])

{

char *map = system_map;

struct _module module;

int fd;

int ch;

int retval = 0;

while ((ch = getopt(argc, argv, "m:tf")) != EOF) {

switch (ch) {

case 'm':

map = optarg;

break;

case 't':

++run;

break;

case 'f':

++force;

break;

}

}

/*

so we can move options in and out without changing the codes idea

of what argv and argc look like.

*/

--optind;

argv += optind;

argc -= optind;

if (argc != 3 && argc != 4) {

fprintf(

stderr,

"usage: k module [-t] [-m map] maddr(hex) [maxlen]\n"

);

exit(1);

}

#ifdef DEBUG

fd = open(argv[1], O_RDWR);

#else

fd = open(argv[1], O_RDONLY);

#endif

if (fd < 0) {

perror("open");

exit(1);

}

if (ksyms_init(map) < 0) {

perror("ksyms_init");

exit(1);

}

module.maxlen = (argc == 4 ? atoi(argv[3]) : -1);

load_module(&module, fd);

init_module(&module, strtoul(argv[2], NULL, 16));

if (run == 0) {

if (error == 0) {

do_module(&module, fd);

} else {

fprintf(

stderr,

"FAILED: (%i) errors. Exiting...\n", error

);

++retval;

}

}

ksyms_cleanup();

exit(retval);

}

 

  摘自《赛迪网》 pragmatic/THC,(版本1.0)/文

 


科技检索


中华网推荐

  • 1000名医生在线咨询

  • 中国足球队官方网站

  • 鸦片玫瑰(新版)

  • 精选股票天地

  • 闪光的flash教程

  • 中华网汽车世界

  • 为你的爱情出谋划策

  • 网文精选——野百合集

  • 世界文化遗产在中国

  • 历届香港小姐风姿集




  • 网络教室编辑信箱
    版权声明 | 本站检索 | 联系方法 | 刊登广告 | 使用说明 | 关于中华网 | 豁免条款

    版权所有 中华网