-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwadsigncheck.c
131 lines (109 loc) · 2.63 KB
/
wadsigncheck.c
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
125
126
127
128
129
130
131
// By BFGR based on Zeventig by Segher
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
// BFGR WadTools v0.39a
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "tools.h"
#define ERROR(s) do { fprintf(stderr, s "\n"); exit(1); } while (0)
static FILE *fp;
static u8 *get_wad(u32 len)
{
u32 rounded_len;
u8 *p;
rounded_len = round_up(len, 0x40);
p = malloc(rounded_len);
if (p == 0)
fatal("malloc");
if (len)
if (fread(p, rounded_len, 1, fp) != 1)
fatal("get_wad read, len = %x", len);
return p;
}
static void do_install_wad(u8 *header)
{
u32 header_len;
u32 cert_len;
u32 tik_len;
u32 tmd_len;
u32 app_len;
u32 trailer_len;
u8 *cert;
u8 *tik;
u8 *tmd;
u32 ret;
header_len = be32(header);
if (header_len != 0x20)
fatal("bad install header length (%x)", header_len);
cert_len = be32(header + 8);
tik_len = be32(header + 0x10);
tmd_len = be32(header + 0x14);
app_len = be32(header + 0x18);
trailer_len = be32(header + 0x1c);
cert = get_wad(cert_len);
tik = get_wad(tik_len);
tmd = get_wad(tmd_len);
printf("Normal sign check...\n");
ret = check_cert_chain(tik, tik_len, cert, cert_len);
if (ret)
fprintf(stderr, "ticket trucha cert failure (%d)\n", ret);
ret = check_cert_chain(tmd, tmd_len, cert, cert_len);
if (ret)
fprintf(stderr, "tmd trucha cert failure (%d)\n", ret);
printf("Trucha sign check...\n");
ret = check_cert_chain_trucha(tik, tik_len, cert, cert_len);
if (ret)
fprintf(stderr, "ticket cert failure (%d)\n", ret);
ret = check_cert_chain_trucha(tmd, tmd_len, cert, cert_len);
if (ret)
fprintf(stderr, "tmd cert failure (%d)\n", ret);
}
static void do_wad(void)
{
u8 header[0x80];
u32 header_len;
u32 header_type;
if (fread(header, 0x40, 1, fp) != 1) {
if (!feof(fp))
fatal("reading wad header");
else
return;
}
header_len = be32(header);
if (header_len >= 0x80)
ERROR("wad header too big\n");
if (header_len >= 0x40)
if (fread(header + 0x40, 0x40, 1, fp) != 1)
fatal("reading wad header (2)");
header_type = be32(header + 4);
switch (header_type) {
case 0x49730000:
do_install_wad(header);
break;
case 0x69620000:
do_install_wad(header);
break;
default:
fatal("unknown header type %08x", header_type);
}
}
int main(int argc, char **argv)
{
printf("--- WAD Sign Checker ---\n");
if (argc!=2) {
printf("--- USAGE: wadsigncheck wad_file ---\n");
exit(-1);
}
fp = fopen(argv[1], "rb");
if (!fp) {
printf("Cannot open file %s.\n", argv[1]);
exit(-1);
}
do_wad();
fclose(fp);
return 0;
}