Chameleon

Chameleon Commit Details

Date:2012-10-27 06:06:31 (6 years 7 months ago)
Author:Evan Lojewski
Commit:2073
Parents: 2072
Message:Update machOconv to seek to the correct address.
Changes:
M/trunk/i386/util/machOconv.c

File differences

trunk/i386/util/machOconv.c
3838
3939
4040
41
42
43
41
4442
45
46
47
48
43
44
4945
5046
5147
......
5652
5753
5854
59
60
61
62
63
55
56
57
58
59
6460
65
61
62
6663
67
68
69
70
71
64
65
66
7267
73
74
68
69
70
7571
76
72
7773
7874
7975
80
81
82
76
77
78
79
8380
84
85
86
81
82
83
84
8785
88
89
90
91
92
86
87
88
89
9390
94
91
9592
96
93
9794
98
99
100
95
96
97
98
10199
102100
103
104
105
101
102
103
104
106105
107
108
109
106
107
108
109
110110
111111
112
113
112
113
114
115
116
117
118
119
120
114121
115122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
116139
140
141
142
143
144
145
146
147
148
149
150
151
152
117153
118
119
120
121154
122
123
124
125
126
127
128
129
130
131
132155
133
134
135
136
137
138
139
140
141
142
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
143194
144
145
146
147
148
149
150
151
152
153
154
195
196
197
198
199
200
201
202
203
204
205
206
155207
156208
157209
static boolswap_ends;
static unsigned long swap(
unsigned long x
)
static unsigned long swap(unsigned long x)
{
if (swap_ends)
return OSSwapInt32(x);
else
return x;
if (swap_ends)return OSSwapInt32(x);
elsereturn x;
}
int
intnc, ncmds;
char *cp;
if (argc == 2) {
infile = open(argv[1], O_RDONLY);
if (infile < 0)
goto usage;
outfile = fileno(stdout);
if (argc == 2)
{
infile = open(argv[1], O_RDONLY);
if (infile < 0)goto usage;
outfile = fileno(stdout);
}
else if (argc == 3) {
else if (argc == 3)
{
infile = open(argv[1], O_RDONLY);
if (infile < 0)
goto usage;
outfile = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (outfile < 0)
goto usage;
if (infile < 0)goto usage;
outfile = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (outfile < 0)goto usage;
}
else {
usage:
else
{
usage:
fprintf(stderr, "usage: machOconv inputfile [outputfile]\n");
exit(1);
exit(1);
}
nc = read(infile, &mh, sizeof (mh));
if (nc < 0) {
perror("read mach header");
exit(1);
if (nc < 0)
{
perror("read mach header");
exit(1);
}
if (nc < (int)sizeof (mh)) {
fprintf(stderr, "read mach header: premature EOF %d\n", nc);
exit(1);
if (nc < (int)sizeof (mh))
{
fprintf(stderr, "read mach header: premature EOF %d\n", nc);
exit(1);
}
if (mh.magic == MH_MAGIC)
swap_ends = false;
else if (mh.magic == MH_CIGAM)
swap_ends = true;
else {
if (mh.magic == MH_MAGIC)swap_ends = false;
else if (mh.magic == MH_CIGAM)swap_ends = true;
else
{
fprintf(stderr, "bad magic number %lx\n", (unsigned long)mh.magic);
exit(1);
exit(1);
}
cmds = calloc(swap(mh.sizeofcmds), sizeof (char));
if (cmds == 0) {
fprintf(stderr, "alloc load commands: no memory\n");
exit(1);
if (cmds == 0)
{
fprintf(stderr, "alloc load commands: no memory\n");
exit(1);
}
nc = read(infile, cmds, swap(mh.sizeofcmds));
if (nc < 0) {
perror("read load commands");
exit(1);
if (nc < 0)
{
perror("read load commands");
exit(1);
}
if (nc < (int)swap(mh.sizeofcmds)) {
fprintf(stderr, "read load commands: premature EOF %d\n", nc);
exit(1);
if (nc < (int)swap(mh.sizeofcmds))
{
fprintf(stderr, "read load commands: premature EOF %d\n", nc);
exit(1);
}
for (ncmds = swap(mh.ncmds), cp = cmds;
ncmds > 0; ncmds--) {
unsigned long vmstart = (unsigned long)-1;
// First pass: determine actual load address
for (ncmds = swap(mh.ncmds), cp = cmds;
ncmds > 0; ncmds--)
{
#define lcp((struct load_command *)cp)
#define scp((struct segment_command *)cp)
boolisDATA;
unsignedvmsize;
unsignedvmaddr;
switch(swap(lcp->cmd))
{
case LC_SEGMENT:
isDATA = (strcmp(scp->segname, "__DATA") == 0);
if (isDATA)
{
vmaddr = swap(scp->vmaddr);
vmsize = swap(scp->filesize);
}
else
{
vmaddr = swap(scp->vmaddr);
vmsize = swap(scp->vmsize);
}
if(vmstart > swap(scp->vmaddr))
{
vmstart = swap(scp->vmaddr);
}
}
cp += swap(lcp->cmdsize);
}
// Second pass: output to file.
for (ncmds = swap(mh.ncmds), cp = cmds;
ncmds > 0; ncmds--)
{
#define lcp((struct load_command *)cp)
switch(swap(lcp->cmd)) {
case LC_SEGMENT:
#define scp((struct segment_command *)cp)
isDATA = (strcmp(scp->segname, "__DATA") == 0);
if (isDATA)
vmsize = swap(scp->filesize);
else
vmsize = swap(scp->vmsize);
result = vm_allocate(mach_task_self(), &data, vmsize, true);
if (result != KERN_SUCCESS) {
mach_error("vm_allocate segment data", result);
exit(1);
}
lseek(infile, swap(scp->fileoff), L_SET);
nc = read(infile, (void *)data, swap(scp->filesize));
if (nc < 0) {
perror("read segment data");
exit(1);
}
if (nc < (int)swap(scp->filesize)) {
fprintf(stderr, "read segment data: premature EOF %d\n", nc);
exit(1);
}
boolisDATA;
unsignedvmsize;
unsignedvmaddr;
switch(swap(lcp->cmd))
{
case LC_SEGMENT:
isDATA = (strcmp(scp->segname, "__DATA") == 0);
if (isDATA)
{
vmaddr = swap(scp->vmaddr);
vmsize = swap(scp->filesize);
}
else
{
vmaddr = swap(scp->vmaddr);
vmsize = swap(scp->vmsize);
}
result = vm_allocate(mach_task_self(), &data, vmsize, true);
if (result != KERN_SUCCESS) {
mach_error("vm_allocate segment data", result);
exit(1);
}
lseek(infile, swap(scp->fileoff), L_SET);
nc = read(infile, (void *)data, swap(scp->filesize));
if (nc < 0) {
perror("read segment data");
exit(1);
}
if (nc < (int)swap(scp->filesize)) {
fprintf(stderr, "read segment data: premature EOF %d\n", nc);
exit(1);
}
// seeking output file
printf("Seek Load Address: 0x%0.8lx\n", swap(scp->vmaddr) - vmstart);
nc = write(outfile, (void *)data, vmsize);
if (nc < (int)vmsize) {
perror("write segment data");
exit(1);
}
vm_deallocate(mach_task_self(), data, vmsize);
break;
}
cp += swap(lcp->cmdsize);
lseek(outfile, swap(scp->vmaddr) - vmstart, L_SET);
nc = write(outfile, (void *)data, vmsize);
if (nc < (int)vmsize) {
perror("write segment data");
exit(1);
}
vm_deallocate(mach_task_self(), data, vmsize);
break;
}
cp += swap(lcp->cmdsize);
}
exit(0);

Archive Download the corresponding diff file

Revision: 2073