// File: /workspace/github_c_makefile_star2_O2/evilwombat[P]gopro-fw-tools/h3-wifi-address.c
// Function: main
int main(int argc, char **argv)
{
	FILE *in_fd;
	char *fname, *output_name;
	struct stat st;
	int ret;
	unsigned int size, hdr_size;
	unsigned char *buf;
	uint32_t crc, hdr_crc;
	int patch_byte = 8;
	struct wifi_fw_type *wifi_fw = wifi_fw_list;

	printf("MAKE SURE YOU HAVE READ THE INSTRUCTIONS!\n");
	printf("The author makes absolutely NO GUARANTEES of the correctness of this program\n");
	printf("and takes absolutely NO RESPONSIBILITY OR LIABILITY for any consequences that\n");
	printf("arise from its use. This program could SEVERELY mess up your camera, totally\n");
	printf("destroy it, cause it to catch fire. It could also destroy your computer, burn\n");
	printf("down your house, etc. The author takes no responsibility for the consequences\n");
	printf("of using this program. Use it at your own risk! You have been warned.\n");
	printf("\n");

	if (argc != 4) {
		print_usage(argv[0]);
		return -1;
	}

	fname = argv[1];

	patch_byte = atoi(argv[2]);

	if (patch_byte < 0 || patch_byte > 255) {
		printf("Bad patching value: %d\n", patch_byte);
		return -1;
	}

	printf("Patching camera address to 10.%d.5.9\n", patch_byte);
	printf("Patching computer address to 10.%d.5.109\n", patch_byte);
	printf("\n");

	output_name = argv[3];

	ret = stat(fname, &st);
	if (ret) {
		printf("Error: Could not stat %s\n", fname);
		return -1;
	}

	size = st.st_size;
	if (size <= 0) {
		printf("Bad file size: %d\n", size);
		return -1;
	}

	buf = malloc(size);
	if (!buf) {
		printf("Could not allocate %d bytes\n", size);
		return -1;
	}

	in_fd = fopen(fname, "rb");

	ret = read_file(in_fd, buf, size);
	if (ret) {
		printf("Could not read file: %d\n", ret);
		return -1;
	}
	fclose(in_fd);

	hdr_size = read_word(buf, SIZE_OFFSET);
	hdr_crc = read_word(buf, CRC_OFFSET);

	printf("Wifi FW header reports size: %08x\n", hdr_size);
	printf("Wifi FW header reports CRC : %08x\n", hdr_crc);

	printf("Actual file size: %08x\n", size);
	if (size != hdr_size) {
		printf("File size does not match size reported in header.\n");
		goto fail;
	}

	write_word(buf, CRC_OFFSET, 0x00000000);
	crc = crc32(buf, size);

	printf("Actual file CRC : %08x\n", crc);
	if (crc != hdr_crc) {
		printf("File CRC does not match CRC reported in header.\n");
		goto fail;
	}

	/*
	 * Checking both the size and CRC is probably redundant, but we may
	 * as well be careful
	 */
	while (wifi_fw->name) {
		if (wifi_fw->size == size && wifi_fw->crc == crc)
			break;
		wifi_fw++;
	}

	if (wifi_fw->name == NULL) {
		printf("\nUnrecognized firmware file!\n");
		printf("This only works on the following firmware files:\n");

		wifi_fw = wifi_fw_list;
		while (wifi_fw->name) {
			printf("\t * %s\n", wifi_fw->name);
			wifi_fw++;
		}

		goto fail;
	}

	printf("Detected firmware type: \"%s\"\n", wifi_fw->name);

	printf("Patching firmware...\n");
	ret = patch_buffer(buf, wifi_fw->patch, patch_byte, wifi_fw->old_val);
	if (ret) {
		printf("Error patching buffer: %d\n", ret);
		goto fail;
	}

	crc = crc32(buf, size);
	printf("New CRC: %08x\n", crc);
	write_word(buf, CRC_OFFSET, crc);

	printf("Saving output file: %s\n", output_name);
	ret = save_file(output_name, size, buf);
	if (ret) {
		printf("Error saving file: %d\n", ret);
		goto fail;
	}
	printf("Done.\n");

fail:
	free(buf);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rsi, %rbx
movl %edi, %ebp
leaq 0x10f3(%rip), %rdi      # 0x22ec
callq 0x1050
leaq 0x1111(%rip), %rdi      # 0x2316
callq 0x1050
leaq 0x1152(%rip), %rdi      # 0x2363
callq 0x1050
leaq 0x1194(%rip), %rdi      # 0x23b1
callq 0x1050
leaq 0x11d5(%rip), %rdi      # 0x23fe
callq 0x1050
leaq 0x1217(%rip), %rdi      # 0x244c
callq 0x1050
leaq 0x1259(%rip), %rdi      # 0x249a
callq 0x1050
pushq $0xa
popq %rdi
callq 0x1040
cmpl $0x4, %ebp
jne 0x127e
movq 0x8(%rbx), %r15
movq 0x10(%rbx), %rdi
callq 0x10c0
movl %eax, %ebp
cmpl $0x100, %eax            # imm = 0x100
jb 0x12c1
leaq 0xe26(%rip), %rdi       # 0x2096
movl %ebp, %esi
xorl %eax, %eax
callq 0x1080
jmp 0x130f
movq (%rbx), %rsi
leaq 0xfd1(%rip), %rdi       # 0x2259
xorl %eax, %eax
callq 0x1080
leaq 0x1315(%rip), %rdi      # 0x25ab
callq 0x1050
leaq 0x133a(%rip), %rdi      # 0x25dc
callq 0x1050
leaq 0x1352(%rip), %rdi      # 0x2600
callq 0x1050
leaq 0x136e(%rip), %rdi      # 0x2628
callq 0x1050
jmp 0x130f
leaq 0xde6(%rip), %rdi       # 0x20ae
movl %ebp, %esi
xorl %eax, %eax
callq 0x1080
leaq 0xdfc(%rip), %rdi       # 0x20d4
movl %ebp, %esi
xorl %eax, %eax
callq 0x1080
pushq $0xa
popq %rdi
callq 0x1040
movq 0x18(%rbx), %r14
leaq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x1090
testl %eax, %eax
je 0x1326
leaq 0xdf9(%rip), %rdi       # 0x20fe
movq %r15, %rsi
xorl %eax, %eax
callq 0x1080
pushq $-0x1
popq %rbx
movl %ebx, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x38(%rsp), %r12
testl %r12d, %r12d
je 0x1433
movl %r12d, %r13d
movq %r13, %rdi
callq 0x10a0
testq %rax, %rax
je 0x1441
movq %rax, %rbx
leaq 0xdf6(%rip), %rsi       # 0x2148
movq %r15, %rdi
callq 0x10b0
movq %rax, %r15
movslq %r13d, %r13
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %r13, %rsi
movq %rax, %rcx
callq 0x1060
cmpl $0x1, %eax
jne 0x1450
movq %r13, (%rsp)
movq %r15, %rdi
callq 0x1070
movq %rbx, %rdi
movl $0x3f8, %esi            # imm = 0x3F8
callq 0x15cc
movl %eax, %r15d
movq %rbx, %rdi
movl $0x3fc, %esi            # imm = 0x3FC
callq 0x15cc
movl %eax, %r13d
leaq 0xdb7(%rip), %rdi       # 0x2164
movl %r15d, %esi
xorl %eax, %eax
callq 0x1080
leaq 0xdc9(%rip), %rdi       # 0x2187
movl %r13d, %esi
xorl %eax, %eax
callq 0x1080
leaq 0xddb(%rip), %rdi       # 0x21aa
movl %r12d, %esi
xorl %eax, %eax
callq 0x1080
cmpl %r12d, %r15d
jne 0x1468
andl $0x0, 0x3fc(%rbx)
movq %rbx, %rdi
movl %r12d, %esi
callq 0x15f4
movq %rax, %r15
leaq 0xdc4(%rip), %rdi       # 0x21c2
movl %r15d, %esi
xorl %eax, %eax
callq 0x1080
cmpl %r15d, %r13d
jne 0x1471
leaq 0x2ce4(%rip), %r15      # 0x40f8
movq -0x18(%r15), %rsi
testq %rsi, %rsi
je 0x148c
cmpl %r12d, -0x10(%r15)
jne 0x142d
cmpl %r13d, -0xc(%r15)
je 0x14ca
addq $0x20, %r15
jmp 0x1414
leaq 0xcde(%rip), %rdi       # 0x2118
xorl %esi, %esi
jmp 0x1272
leaq 0xce3(%rip), %rdi       # 0x212b
movl %r12d, %esi
jmp 0x1272
leaq 0xcf4(%rip), %rdi       # 0x214b
pushq $-0x1
popq %rbx
movl %ebx, %esi
xorl %eax, %eax
callq 0x1080
jmp 0x1312
leaq 0x110a(%rip), %rdi      # 0x2579
jmp 0x1478
leaq 0x10d1(%rip), %rdi      # 0x2549
callq 0x1050
movq %rbx, %rdi
callq 0x1030
xorl %ebx, %ebx
jmp 0x1312
leaq 0x1068(%rip), %rdi      # 0x24fb
callq 0x1050
leaq 0x1079(%rip), %rdi      # 0x2518
callq 0x1050
leaq 0x2c35(%rip), %r15      # 0x40e0
leaq 0xd28(%rip), %r14       # 0x21da
movq (%r15), %rsi
testq %rsi, %rsi
je 0x147d
movq %r14, %rdi
xorl %eax, %eax
callq 0x1080
addq $0x20, %r15
jmp 0x14b2
leaq 0xd11(%rip), %rdi       # 0x21e2
xorl %eax, %eax
callq 0x1080
leaq 0x1001(%rip), %rdi      # 0x24e0
callq 0x1050
movq (%r15), %rax
movzbl -0x8(%r15), %edx
movq (%rsp), %r13
movslq (%rax), %rsi
cmpq $-0x1, %rsi
je 0x150f
movzbl (%rbx,%rsi), %ecx
cmpb %dl, %cl
jne 0x158e
movb %bpl, (%rbx,%rsi)
addq $0x4, %rax
jmp 0x14f0
movq %rbx, %rdi
movl %r12d, %esi
callq 0x15f4
movq %rax, %r15
leaq 0xcf7(%rip), %rdi       # 0x221b
movl %r15d, %esi
xorl %eax, %eax
callq 0x1080
bswapl %r15d
movl %r15d, 0x3fc(%rbx)
leaq 0xceb(%rip), %rdi       # 0x222a
movq %r14, %rsi
xorl %eax, %eax
callq 0x1080
leaq 0xd81(%rip), %rsi       # 0x22d1
movq %r14, %rdi
callq 0x10b0
testq %rax, %rax
je 0x15a5
movq %rax, %r15
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %r13, %rsi
movq %rax, %rcx
callq 0x10d0
movq %rax, %r14
movq %r15, %rdi
callq 0x1070
cmpl $0x1, %r14d
jne 0x15b6
leaq 0xf6c(%rip), %rdi       # 0x24f5
jmp 0x1478
leaq 0xd01(%rip), %rdi       # 0x2296
xorl %eax, %eax
callq 0x1080
leaq 0xc5d(%rip), %rdi       # 0x2200
jmp 0x15bd
leaq 0xd29(%rip), %rdi       # 0x22d5
movq %r14, %rsi
xorl %eax, %eax
callq 0x1080
leaq 0xc85(%rip), %rdi       # 0x2242
pushq $-0x1
popq %rsi
xorl %eax, %eax
callq 0x1080
jmp 0x147d