// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/exepack.c
// Function: find_decoder_len
static void find_decoder_len(deark *c, lctx *d)
{
	int ret;
	int method = 0;
	i64 foundpos = 0;
	i64 haystack_pos;
	i64 haystack_len;
	i64 n;

	// Something to consider: We could simply have a lookup table of
	// known decoder_fingerprints to decoder lengths.
	// It is safe (barring CRC collisions), because the fingerprinted bytes
	// include the pointer to the compressed relocation table.
	// But hardcoding CRC values is a maintenance hassle, and the other
	// methods will always work for all known EXEPACK variants.

	// Look for the pattern that usually follows the pointer to the compressed
	// relocation table.
	// Known offsets range from ep+135 to ep+148
	haystack_pos = d->host_ei->entry_point+100;
	haystack_len = 100;
	ret = dbuf_search(c->infile, (const u8*)"\x0e\x1f\x8b\x1e\x04\x00\xfc\x33", 8,
		haystack_pos, haystack_len, &foundpos);
	if(ret) {
		n = de_getu16le(foundpos-2);
		d->decoder_len = n - d->host_ei->regIP;
		method = 1;
		goto done;
	}

	// If that failed (which it will for some unusual or patched variants),
	// use the error-message-pointer that we believe is always right before
	// the "epilog". We assume the "Packed file is corrupt" error message
	// size is always 22 bytes, and that the compressed relocation table
	// follows. (The error message size does appear in the file, but not at
	// a consistent location. And if it's less than 22 bytes, it wouldn't
	// help us anyway.)
	// I know of no files for which this method fails, but it's possible
	// that some exist. Let's hope the first method works in such cases.
	n = de_getu16le(d->epilog_pos - 2);
	d->decoder_len = n + 22 - d->host_ei->regIP;
	method = 2;

done:
	if(d->decoder_len) {
		// Check that decoder_len is sane.
		// Known decoder lengths are from 256 to 291.
		if(d->decoder_len<180 || d->decoder_len>400) {
			d->decoder_len = 0;
		}
	}

	if(d->decoder_len) {
		de_dbg(c, "decoder len: %"I64_FMT" (found by method %d)", d->decoder_len, method);
	}
	else {
		de_err(c, "Could not find relocation table");
		d->errmsg_handled = 1;
		d->errflag = 1;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x40(%rax), %rax
addq $0x64, %rax
movq %rax, -0x28(%rbp)
movq $0x64, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %r8
leaq 0x145a17(%rip), %rsi    # 0x1a98e9
movl $0x8, %edx
leaq -0x20(%rbp), %r9
callq 0x169370
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x63f23
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x20(%rbp), %rsi
subq $0x2, %rsi
callq 0x165280
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
subq 0x28(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movl $0x1, -0x18(%rbp)
jmp 0x63f63
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rsi
subq $0x2, %rsi
callq 0x165280
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
addq $0x16, %rcx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
subq 0x28(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movl $0x2, -0x18(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x63f98
movq -0x10(%rbp), %rax
cmpq $0xb4, 0x20(%rax)
jl 0x63f8a
movq -0x10(%rbp), %rax
cmpq $0x190, 0x20(%rax)      # imm = 0x190
jle 0x63f96
movq -0x10(%rbp), %rax
movq $0x0, 0x20(%rax)
jmp 0x63f98
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x63fc2
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdx
movl -0x18(%rbp), %ecx
leaq 0x14574c(%rip), %rsi    # 0x1a9705
movb $0x0, %al
callq 0x15b0d0
jmp 0x63fe9
movq -0x8(%rbp), %rdi
leaq 0x14575e(%rip), %rsi    # 0x1a972b
movb $0x0, %al
callq 0x15bfb0
movq -0x10(%rbp), %rax
movl $0x1, 0x4(%rax)
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
addq $0x40, %rsp
popq %rbp
retq
nop