// File: /workspace/github_c_makefile_star2_O2/mikeakohn[P]print_pe/build/../src/vb.c
// Function: vb_info_print
int vb_info_print(
  FILE *in,
  struct optional_header_t *optional_header,
  struct section_header_t *section_header)
{
  struct vb_header_t vb_header;
  struct com_reg_data_t com_reg_data;
  struct reg_info_t reg_info;
  int marker,ptr;
  int t;
  int addr;

  marker = ftell(in);
  fseek(in, (optional_header->AddressOfEntryPoint - section_header->VirtualAddress) + section_header->PointerToRawData, SEEK_SET);

  ptr = getc(in);
  /* Compiled VB executables / DLLs have a couple of entry point signitures. */
  /* 0x68, 0x90, 0x5A */
  switch (ptr)
  {
    case 0x5a: /* 0x5A = POP EDX, this means the file might be a VB DLL or OCX. */
	    /* The pointer to the VB5! data stuff is in the first exported function. Usually DllCanUnloadNow()
	     * Once we get to that address it turns into case 0x68 again. */
	    /* Get the address to the export directory */
	    addr = (optional_header->directory_entry[0].virtual_address - section_header->VirtualAddress) + section_header->PointerToRawData;
	    /* ExportDirectory->AddressOfFunctions = addr+28; */
	    addr = get_ptr(in, get_ptr(in,(addr + 28)));
	    fseek(in, addr + 2, SEEK_SET); /* read past 0x58, 0x68 */
	    ptr = read_uint16(in);
	    break;
    case 0x90: /* 0x90 = NOP, then it's case 0x68 */
	    getc(in); /* read the NOP then fall through to case 0x68 */
    case 0x68: /* 0x68 = PUSH (word) */
	    ptr = read_uint16(in);
	    break;
    default:
	    fseek(in, marker, SEEK_SET);
	    return -2;
	    break;
  }

  if (section_header->VirtualAddress <= ptr &&
      ptr < section_header->VirtualAddress + section_header->SizeOfRawData)
  {
    fseek(in, (ptr - section_header->VirtualAddress) + section_header->PointerToRawData, SEEK_SET);
  }
    else
  {
    fseek(in, marker, SEEK_SET);
    return -3;
  }

  read_chars(in, vb_header.szVbMagic, 4);

  if (strcmp(vb_header.szVbMagic, "VB5!") != 0)
  {
    fseek(in, marker, SEEK_SET);
    return -1;
  }

  vb_header.wRuntimeBuild = read_uint16(in);
  read_chars(in, vb_header.szLangDll, 14);
  read_chars(in, vb_header.szSecLangDll, 14);
  vb_header.wRuntimeRevision = read_uint16(in);
  vb_header.dwLCID = read_uint32(in);
  vb_header.dwSecLCID = read_uint32(in);
  vb_header.lpSubMain = read_uint32(in);
  vb_header.lpProjectData = read_uint32(in);
  vb_header.fMdlIntCtls = read_uint32(in);
  vb_header.fMdlIntCtls2 = read_uint32(in);
  vb_header.dwThreadFlags = read_uint32(in);
  vb_header.dwThreadCount = read_uint32(in);
  vb_header.wFormCount = read_uint16(in);
  vb_header.wExternalCount = read_uint16(in);
  vb_header.dwThunkCount = read_uint32(in);
  vb_header.lpGuiTable = read_uint32(in);
  vb_header.lpExternalTable = read_uint32(in);
  vb_header.lpComRegisterData = read_uint32(in);
  vb_header.bSzProjectDescription = read_uint32(in);
  vb_header.bSzProjectExeName = read_uint32(in);
  vb_header.bSzProjectHelpFile = read_uint32(in);
  vb_header.bSzProjectName = read_uint32(in);

  printf("  -- VB Header --\n");
  printf("         szVbMagic: %s\n", vb_header.szVbMagic);
  printf("     wRuntimeBuild: %d\n", vb_header.wRuntimeBuild);
  printf("         szLangDll: %s\n", vb_header.szLangDll);
  printf("      szSecLangDll: %s\n", vb_header.szSecLangDll);
  printf("  wRuntimeRevision: %d\n", vb_header.wRuntimeRevision);
  printf("            dwLCID: %d\n", vb_header.dwLCID);
  printf("         dwSecLCID: %d\n", vb_header.dwSecLCID);
  printf("         lpSubMain: %d\n", vb_header.lpSubMain);
  printf("     lpProjectData: %d\n", vb_header.lpProjectData);
  printf("       fMdlIntCtls: 0x%08x\n", vb_header.fMdlIntCtls);
  printf("      fMdlIntCtls2: 0x%08x\n", vb_header.fMdlIntCtls2);
  printf("     dwThreadFlags: %d", vb_header.dwThreadFlags);
  printf(" (");

  if ((vb_header.dwThreadFlags & 1) == 1) printf(" ApartmentModel");
  if ((vb_header.dwThreadFlags & 2) == 2) printf(" RequireLicense");
  if ((vb_header.dwThreadFlags & 4) == 4) printf(" Unattended");
  if ((vb_header.dwThreadFlags & 8) == 8) printf(" SingleThreaded");
  if ((vb_header.dwThreadFlags & 16) == 16) printf(" Retained");

  printf(" )\n");
  printf("     dwThreadCount: %d\n", vb_header.dwThreadCount);
  printf("        wFormCount: %d\n", vb_header.wFormCount);
  printf("    wExternalCount: %d\n", vb_header.wExternalCount);
  printf("      dwThunkCount: %d\n", vb_header.dwThunkCount);
  printf("        lpGuiTable: %d\n", vb_header.lpGuiTable);
  printf("   lpExternalTable: %d\n", vb_header.lpExternalTable);
  printf(" lpComRegisterData: %d\n", vb_header.lpComRegisterData);
  printf("    bSzProjectDesc: %d (", vb_header.bSzProjectDescription);
  print_string(in, ((vb_header.bSzProjectDescription+ptr)-section_header->VirtualAddress)+section_header->PointerToRawData);
  printf(")\n");
  printf(" bSzProjectExeName: %d (",vb_header.bSzProjectExeName);
  print_string(in, ((vb_header.bSzProjectExeName + ptr) - section_header->VirtualAddress) + section_header->PointerToRawData);
  printf(")\n");
  printf("bSzProjectHelpFile: %d (",vb_header.bSzProjectHelpFile);
  print_string(in, ((vb_header.bSzProjectHelpFile + ptr) - section_header->VirtualAddress) + section_header->PointerToRawData);
  printf(")\n");
  printf("    bSzProjectName: %d (",vb_header.bSzProjectName);
  print_string(in, ((vb_header.bSzProjectName + ptr) - section_header->VirtualAddress) + section_header->PointerToRawData);
  printf(")\n");
  printf("\n");

  if (vb_header.lpComRegisterData != 0)
  {
    com_reg_data_read(&com_reg_data, in, vb_header.lpComRegisterData - optional_header->ImageBase);

    com_reg_data_print(&com_reg_data);

    if (com_reg_data.bRegInfo != 0)
    {
      t = com_reg_data.bRegInfo;

      while (1)
      {
        reg_info_read(&reg_info, in, vb_header.lpComRegisterData - optional_header->ImageBase + t);

        get_string(in, (char *)reg_info.szObjectName, vb_header.lpComRegisterData - optional_header->ImageBase + reg_info.bObjectName);

        reg_info_print(&reg_info);

        if (reg_info.bNextObject == 0) { break; }

        t = reg_info.bNextObject;
      }
    }
  }

  fseek(in, marker, SEEK_SET);

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4e8, %rsp            # imm = 0x4E8
movq %rdx, %r12
movq %rsi, %r15
movq %rdi, %rbx
callq 0x30f0
movq %rax, %r13
movl 0x10(%r15), %esi
subl 0x10(%r12), %esi
addl 0x18(%r12), %esi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3110
movq %rbx, %rdi
callq 0x3160
cmpl $0x90, %eax
je 0x6da7
cmpl $0x68, %eax
je 0x6daf
cmpl $0x5a, %eax
jne 0x6e27
movl 0x7c(%r15), %eax
movl 0x18(%r12), %ecx
subl 0x10(%r12), %eax
leal (%rax,%rcx), %esi
addl $0x1c, %esi
movq %rbx, %rdi
callq 0x531c
movq %rbx, %rdi
movl %eax, %esi
callq 0x531c
addl $0x2, %eax
movslq %eax, %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3110
jmp 0x6daf
movq %rbx, %rdi
callq 0x3160
movq %rbx, %rdi
callq 0x5168
movl %eax, %ebp
movl 0x10(%r12), %eax
movl %ebp, %esi
subl %eax, %esi
jb 0x6e16
addl 0x14(%r12), %eax
cmpl %eax, %ebp
jae 0x6e16
addl 0x18(%r12), %esi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3110
leaq 0x8(%rsp), %r14
pushq $0x4
popq %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x518e
leaq 0x3d6f(%rip), %rsi      # 0xab65
pushq $0x5
popq %rdx
movq %r14, %rdi
callq 0x3100
testl %eax, %eax
je 0x6e4d
movslq %r13d, %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3110
pushq $-0x1
jmp 0x6e36
movslq %r13d, %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3110
pushq $-0x3
jmp 0x6e36
movslq %r13d, %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3110
pushq $-0x2
popq %r13
movl %r13d, %eax
addq $0x4e8, %rsp            # imm = 0x4E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r13, (%rsp)
movq %rbx, %rdi
callq 0x5168
leaq 0x10(%rsp), %rsi
movw %ax, -0x2(%rsi)
pushq $0xe
popq %r14
movq %rbx, %rdi
movl %r14d, %edx
callq 0x518e
leaq 0x1f(%rsp), %r13
movq %rbx, %rdi
movq %r13, %rsi
movl %r14d, %edx
callq 0x518e
movq %rbx, %rdi
callq 0x5168
movw %ax, 0xf(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x11(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x15(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x19(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x1d(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x21(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x25(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x29(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x2d(%r13)
movq %rbx, %rdi
callq 0x5168
movw %ax, 0x31(%r13)
movq %rbx, %rdi
callq 0x5168
movw %ax, 0x33(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x35(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x39(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x3d(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x41(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x45(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x49(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x4d(%r13)
movq %rbx, %rdi
callq 0x5126
movl %eax, 0x51(%r13)
leaq 0x3e71(%rip), %rdi      # 0xade3
callq 0x3060
leaq 0x3bec(%rip), %rdi      # 0xab6a
leaq 0x8(%rsp), %r14
movq %r14, %rsi
xorl %eax, %eax
callq 0x3090
movzwl 0x6(%r14), %esi
leaq 0x3be9(%rip), %rdi      # 0xab82
xorl %eax, %eax
callq 0x3090
leaq 0x3bf3(%rip), %rdi      # 0xab9a
leaq 0x10(%rsp), %rsi
xorl %eax, %eax
callq 0x3090
leaq 0x3bf8(%rip), %rdi      # 0xabb2
movq %r13, %rsi
xorl %eax, %eax
callq 0x3090
movzwl 0x26(%r14), %esi
leaq 0x3bfa(%rip), %rdi      # 0xabca
xorl %eax, %eax
callq 0x3090
movl 0x28(%r14), %esi
leaq 0x3c00(%rip), %rdi      # 0xabe2
xorl %eax, %eax
callq 0x3090
movl 0x2c(%r14), %esi
leaq 0x3c06(%rip), %rdi      # 0xabfa
xorl %eax, %eax
callq 0x3090
movl 0x30(%r14), %esi
leaq 0x3c0c(%rip), %rdi      # 0xac12
xorl %eax, %eax
callq 0x3090
movl 0x34(%r14), %esi
leaq 0x3c12(%rip), %rdi      # 0xac2a
xorl %eax, %eax
callq 0x3090
movl 0x38(%r14), %esi
leaq 0x3c18(%rip), %rdi      # 0xac42
xorl %eax, %eax
callq 0x3090
movl 0x3c(%r14), %esi
leaq 0x3c22(%rip), %rdi      # 0xac5e
xorl %eax, %eax
callq 0x3090
movl 0x40(%r14), %esi
leaq 0x3c2c(%rip), %rdi      # 0xac7a
xorl %eax, %eax
callq 0x3090
leaq 0x3d39(%rip), %rdi      # 0xad95
xorl %eax, %eax
callq 0x3090
movl 0x40(%r14), %eax
testb $0x1, %al
je 0x707d
leaq 0x3c1f(%rip), %rdi      # 0xac91
xorl %eax, %eax
callq 0x3090
movl 0x48(%rsp), %eax
testb $0x2, %al
je 0x7093
leaq 0x3c19(%rip), %rdi      # 0xaca1
xorl %eax, %eax
callq 0x3090
movl 0x48(%rsp), %eax
testb $0x4, %al
je 0x70a9
leaq 0x3c13(%rip), %rdi      # 0xacb1
xorl %eax, %eax
callq 0x3090
movl 0x48(%rsp), %eax
testb $0x8, %al
je 0x70bf
leaq 0x3c09(%rip), %rdi      # 0xacbd
xorl %eax, %eax
callq 0x3090
movl 0x48(%rsp), %eax
testb $0x10, %al
je 0x70d1
leaq 0x3c03(%rip), %rdi      # 0xaccd
xorl %eax, %eax
callq 0x3090
leaq 0x3d1d(%rip), %rdi      # 0xadf5
callq 0x3060
movl 0x4c(%rsp), %esi
leaq 0x3bef(%rip), %rdi      # 0xacd7
xorl %r13d, %r13d
xorl %eax, %eax
callq 0x3090
movzwl 0x50(%rsp), %esi
leaq 0x3bf1(%rip), %rdi      # 0xacef
xorl %eax, %eax
callq 0x3090
movzwl 0x52(%rsp), %esi
leaq 0x3bf6(%rip), %rdi      # 0xad07
xorl %eax, %eax
callq 0x3090
movl 0x54(%rsp), %esi
leaq 0x3bfc(%rip), %rdi      # 0xad1f
xorl %eax, %eax
callq 0x3090
movl 0x58(%rsp), %esi
leaq 0x3c02(%rip), %rdi      # 0xad37
xorl %eax, %eax
callq 0x3090
movl 0x5c(%rsp), %esi
leaq 0x3c08(%rip), %rdi      # 0xad4f
xorl %eax, %eax
callq 0x3090
movl 0x60(%rsp), %esi
leaq 0x3c0e(%rip), %rdi      # 0xad67
xorl %eax, %eax
callq 0x3090
movl 0x64(%rsp), %esi
leaq 0x3c14(%rip), %rdi      # 0xad7f
xorl %eax, %eax
callq 0x3090
movl 0x64(%rsp), %esi
addl %ebp, %esi
subl 0x10(%r12), %esi
addl 0x18(%r12), %esi
movq %rbx, %rdi
callq 0x5270
leaq 0x3c65(%rip), %r14      # 0xadf6
movq %r14, %rdi
callq 0x3060
movl 0x68(%rsp), %esi
leaq 0x3bf4(%rip), %rdi      # 0xad98
xorl %eax, %eax
callq 0x3090
movl 0x68(%rsp), %esi
addl %ebp, %esi
subl 0x10(%r12), %esi
addl 0x18(%r12), %esi
movq %rbx, %rdi
callq 0x5270
movq %r14, %rdi
callq 0x3060
movl 0x6c(%rsp), %esi
leaq 0x3bdb(%rip), %rdi      # 0xadb1
xorl %eax, %eax
callq 0x3090
movl 0x6c(%rsp), %esi
addl %ebp, %esi
subl 0x10(%r12), %esi
addl 0x18(%r12), %esi
movq %rbx, %rdi
callq 0x5270
movq %r14, %rdi
callq 0x3060
movl 0x70(%rsp), %esi
leaq 0x3bc2(%rip), %rdi      # 0xadca
xorl %eax, %eax
callq 0x3090
addl 0x70(%rsp), %ebp
subl 0x10(%r12), %ebp
addl 0x18(%r12), %ebp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x5270
movq %r14, %rdi
callq 0x3060
pushq $0xa
popq %rdi
callq 0x3030
movl 0x60(%rsp), %edx
testl %edx, %edx
je 0x72b2
subl 0x20(%r15), %edx
leaq 0x74(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3e3a
movq %r14, %rdi
callq 0x3ee9
movl (%r14), %edx
testl %edx, %edx
je 0x72b2
leaq 0xe8(%rsp), %r14
leaq 0xa0(%rsp), %r12
addl 0x60(%rsp), %edx
subl 0x20(%r15), %edx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3bd0
movl 0x60(%rsp), %edx
subl 0x20(%r15), %edx
addl 0xa4(%rsp), %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x52bb
movq %r12, %rdi
callq 0x3ce0
movl 0xa0(%rsp), %edx
testl %edx, %edx
jne 0x7272
movslq (%rsp), %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3110
jmp 0x6e38