aboutsummaryrefslogtreecommitdiff
path: root/src/libmach/crack.c
blob: c186456a661331990ed2d731012b3e4b617471bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include "elf.h"

static struct
{
	ulong magic;
	int (*fn)(int, Fhdr*);
} cracktab[] = {
	0x7F454C46,	crackelf,
	0xFEEDFACE,	crackmacho,
};

Fhdr*
crackhdr(char *name, int mode)
{
	uchar buf[4];
	ulong magic;
	int i, fd;
	Fhdr *hdr;

	if((fd = open(name, mode)) < 0)
		return nil;

	if(seek(fd, 0, 0) < 0 || readn(fd, buf, 4) != 4){
		close(fd);
		return nil;
	}

	hdr = mallocz(sizeof(Fhdr), 1);
	if(hdr == nil){
		close(fd);
		return nil;
	}
	hdr->filename = strdup(name);
	magic = beload4(buf);
	werrstr("magic doesn't match");
	for(i=0; i<nelem(cracktab); i++)
		if(cracktab[i].magic == magic && seek(fd, 0, 0) == 0 && cracktab[i].fn(fd, hdr) >= 0){
			_addhdr(hdr);
			return hdr;
		}
	werrstr("unknown file type: %r");
	free(hdr);
	close(fd);
	return nil;
}

void
uncrackhdr(Fhdr *hdr)
{
	int i;

	symclose(hdr);
	if(hdr->elf)
		elfclose(hdr->elf);
	if(hdr->fd >= 0)
		close(hdr->fd);
	free(hdr->cmdline);
	free(hdr->prog);
	for(i=0; i<hdr->nthread; i++)
		free(hdr->thread[i].ureg);
	free(hdr->thread);
	free(hdr);
}

int
mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs)
{
	if(fp == nil){
		werrstr("no file");
		return -1;
	}
	if(map == nil){
		werrstr("no map");
		return -1;
	}
	if(fp->map == 0){
		werrstr("cannot load map for this file type");
		return -1;
	}
	if(regs)
		*regs = nil;
	return fp->map(fp, base, map, regs);
}

void
unmapfile(Fhdr *fp, Map *map)
{
	int i;

	if(map == nil || fp == nil)
		return;

	for(i=0; i<map->nseg; i++){
		while(i<map->nseg && map->seg[i].fd == fp->fd){
			map->nseg--;
			memmove(&map->seg[i], &map->seg[i+1], 
				(map->nseg-i)*sizeof(map->seg[0]));
		}
	}
}

Regs*
coreregs(Fhdr *fp, uint id)
{
	UregRegs *r;
	int i;

	for(i=0; i<fp->nthread; i++){
		if(fp->thread[i].id == id){
			if((r = mallocz(sizeof *r, 1)) == nil)
				return nil;
			r->r.rw = _uregrw;
			r->ureg = fp->thread[i].ureg;
			return &r->r;
		}
	}
	werrstr("thread not found");
	return nil;
}