// age.cc
// 6/1/2014 jichi
// See: http://bbs.sumisora.org/read.php?tid=11044256
// See also ATCode: http://capita.tistory.com/m/post/255
#include "engine/model/age.h"
#include "engine/enginecontroller.h"
#include "engine/enginedef.h"
#include "engine/engineutil.h"
#include "hijack/hijackfuns.h"
#include "hijack/hijackmanager.h"
#include "memdbg/memsearch.h"
#include "disasm/disasm.h"
#include "winasm/winasmutil.h"
#include "winhook/hookcode.h"
#include "winhook/hookfun.h"
#include "winhook/hookcall.h"
#include <qt_windows.h>
#include <cstdint>

#define DEBUG "model/age"
#include "sakurakit/skdebug.h"

namespace { // unnamed
namespace ScenarioHook {
namespace Private {
  /**
   *  Sample game: 姫狩りダンジョンマイスター体験版
   *  Observations:
   *  - ecx: this, must be preserved
   *  - arg1: 0
   *  - arg2: LPCSTR
   *  - arg3: 0
   *  - arg4: 0
   *  - arg5: LPVOID  to unknown
   *  - return: TRUE(1) if succeed
   *
   * FIXME 6/1/2014: This will crash in Chinese locale
   */
  bool hookBefore(winhook::hook_stack *s)
  {
    static QByteArray data_; // persistent storage, which makes this function not thread-safe

    // All threads including character names are linked together
    enum { role = Engine::ScenarioRole, sig = 0 };

    LPCSTR text = (LPCSTR)s->stack[2]; // arg2

    data_ = EngineController::instance()->dispatchTextA(text, role, sig);
    s->stack[2] = (ulong)data_.constData(); // arg2
    return true;
  }

} // namespace Private

/**
 *  Sample game: 神採りアルケミーマイスター
 *
 *  The caller of the last GetTextExtentPoint32A:
 *
 *  0045AB15   E8 04B20F00      CALL .00555D1E
 *  0045AB1A   8BE5             MOV ESP,EBP
 *  0045AB1C   5D               POP EBP
 *  0045AB1D   C2 1000          RETN 0x10
 *  0045AB20   55               PUSH EBP
 *  0045AB21   8BEC             MOV EBP,ESP
 *  0045AB23   6A FF            PUSH -0x1
 *  0045AB25   68 E9015700      PUSH .005701E9
 *  0045AB2A   64:A1 00000000   MOV EAX,DWORD PTR FS:[0]
 *  0045AB30   50               PUSH EAX
 *  0045AB31   81EC FC000000    SUB ESP,0xFC
 *  0045AB37   A1 50575C00      MOV EAX,DWORD PTR DS:[0x5C5750]
 *  0045AB3C   33C5             XOR EAX,EBP
 *  0045AB3E   8945 F0          MOV DWORD PTR SS:[EBP-0x10],EAX
 *  0045AB41   53               PUSH EBX
 *
 *  Sample game: 神のラプソディ
 *
 *  004689AC   CC               INT3
 *  004689AD   CC               INT3
 *  004689AE   CC               INT3
 *  004689AF   CC               INT3
 *  004689B0   55               PUSH EBP
 *  004689B1   8BEC             MOV EBP,ESP
 *  004689B3   6A FF            PUSH -0x1
 *  004689B5   68 99116100      PUSH .00611199
 *  004689BA   64:A1 00000000   MOV EAX,DWORD PTR FS:[0]
 *  004689C0   50               PUSH EAX
 *  004689C1   81EC 04010000    SUB ESP,0x104
 *  004689C7   A1 80D36600      MOV EAX,DWORD PTR DS:[0x66D380]
 *  004689CC   33C5             XOR EAX,EBP
 *  004689CE   8945 F0          MOV DWORD PTR SS:[EBP-0x10],EAX
 *  004689D1   53               PUSH EBX
 *  004689D2   56               PUSH ESI
 *  004689D3   57               PUSH EDI
 *  004689D4   50               PUSH EAX
 *  004689D5   8D45 F4          LEA EAX,DWORD PTR SS:[EBP-0xC]
 *  004689D8   64:A3 00000000   MOV DWORD PTR FS:[0],EAX
 *  004689DE   8B7D 08          MOV EDI,DWORD PTR SS:[EBP+0x8]
 *  004689E1   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+0xC]
 *  004689E4   8BD9             MOV EBX,ECX
 *  004689E6   8B4D 10          MOV ECX,DWORD PTR SS:[EBP+0x10]
 *  004689E9   33F6             XOR ESI,ESI
 *  004689EB   89BD 10FFFFFF    MOV DWORD PTR SS:[EBP-0xF0],EDI
 *  004689F1   8985 F8FEFFFF    MOV DWORD PTR SS:[EBP-0x108],EAX
 *  004689F7   898D FCFEFFFF    MOV DWORD PTR SS:[EBP-0x104],ECX
 *  004689FD   C745 D0 0F000000 MOV DWORD PTR SS:[EBP-0x30],0xF
 *  00468A04   8975 CC          MOV DWORD PTR SS:[EBP-0x34],ESI
 *  00468A07   C645 BC 00       MOV BYTE PTR SS:[EBP-0x44],0x0
 *  00468A0B   BA 01000000      MOV EDX,0x1
 *  00468A10   8955 FC          MOV DWORD PTR SS:[EBP-0x4],EDX
 *  00468A13   8038 00          CMP BYTE PTR DS:[EAX],0x0
 *  00468A16   75 11            JNZ SHORT .00468A29
 *  00468A18   C745 FC FFFFFFFF MOV DWORD PTR SS:[EBP-0x4],-0x1
 *  00468A1F   8975 CC          MOV DWORD PTR SS:[EBP-0x34],ESI
 *  00468A22   33C0             XOR EAX,EAX
 *  00468A24   E9 E20B0000      JMP .0046960B
 *  00468A29   3BFE             CMP EDI,ESI
 *  00468A2B   75 0C            JNZ SHORT .00468A39
 *  00468A2D   8BBB CC040000    MOV EDI,DWORD PTR DS:[EBX+0x4CC]
 *  00468A33   89BD 10FFFFFF    MOV DWORD PTR SS:[EBP-0xF0],EDI
 *  00468A39   8BB4BB 14040000  MOV ESI,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468A40   C685 56FFFFFF 00 MOV BYTE PTR SS:[EBP-0xAA],0x0
 *  00468A47   8985 44FFFFFF    MOV DWORD PTR SS:[EBP-0xBC],EAX
 *  00468A4D   898D 38FFFFFF    MOV DWORD PTR SS:[EBP-0xC8],ECX
 *  00468A53   8985 3CFFFFFF    MOV DWORD PTR SS:[EBP-0xC4],EAX
 *  00468A59   3956 70          CMP DWORD PTR DS:[ESI+0x70],EDX
 *  00468A5C   75 1A            JNZ SHORT .00468A78
 *  00468A5E   8B55 14          MOV EDX,DWORD PTR SS:[EBP+0x14]
 *  00468A61   52               PUSH EDX
 *  00468A62   51               PUSH ECX
 *  00468A63   50               PUSH EAX
 *  00468A64   57               PUSH EDI
 *  00468A65   8BCB             MOV ECX,EBX
 *  00468A67   E8 C4F3FFFF      CALL .00467E30
 *  00468A6C   C745 FC FFFFFFFF MOV DWORD PTR SS:[EBP-0x4],-0x1
 *  00468A73   E9 8C0B0000      JMP .00469604
 *  00468A78   8B83 6C050000    MOV EAX,DWORD PTR DS:[EBX+0x56C]
 *  00468A7E   8B8B 68050000    MOV ECX,DWORD PTR DS:[EBX+0x568]
 *  00468A84   50               PUSH EAX
 *  00468A85   8B83 94550300    MOV EAX,DWORD PTR DS:[EBX+0x35594]
 *  00468A8B   51               PUSH ECX
 *  00468A8C   8B8B 54050000    MOV ECX,DWORD PTR DS:[EBX+0x554]
 *  00468A92   50               PUSH EAX
 *  00468A93   8B83 58050000    MOV EAX,DWORD PTR DS:[EBX+0x558]
 *  00468A99   51               PUSH ECX
 *  00468A9A   8B8B 50050000    MOV ECX,DWORD PTR DS:[EBX+0x550]
 *  00468AA0   50               PUSH EAX
 *  00468AA1   8B83 5C050000    MOV EAX,DWORD PTR DS:[EBX+0x55C]
 *  00468AA7   51               PUSH ECX
 *  00468AA8   8B8B D4130300    MOV ECX,DWORD PTR DS:[EBX+0x313D4]
 *  00468AAE   50               PUSH EAX
 *  00468AAF   51               PUSH ECX
 *  00468AB0   83EC 1C          SUB ESP,0x1C
 *  00468AB3   8BCC             MOV ECX,ESP
 *  00468AB5   33D2             XOR EDX,EDX
 *  00468AB7   89A5 28FFFFFF    MOV DWORD PTR SS:[EBP-0xD8],ESP
 *  00468ABD   6A FF            PUSH -0x1
 *  00468ABF   8993 7C140300    MOV DWORD PTR DS:[EBX+0x3147C],EDX
 *  00468AC5   C783 98550300 01>MOV DWORD PTR DS:[EBX+0x35598],0x1
 *  00468ACF   8D83 AC550300    LEA EAX,DWORD PTR DS:[EBX+0x355AC]
 *  00468AD5   52               PUSH EDX
 *  00468AD6   C741 14 0F000000 MOV DWORD PTR DS:[ECX+0x14],0xF
 *  00468ADD   8951 10          MOV DWORD PTR DS:[ECX+0x10],EDX
 *  00468AE0   50               PUSH EAX
 *  00468AE1   8811             MOV BYTE PTR DS:[ECX],DL
 *  00468AE3   E8 1830FAFF      CALL .0040BB00
 *  00468AE8   C645 FC 04       MOV BYTE PTR SS:[EBP-0x4],0x4
 *  00468AEC   C645 FC 01       MOV BYTE PTR SS:[EBP-0x4],0x1
 *  00468AF0   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468AF7   E8 7414FFFF      CALL .00459F70
 *  00468AFC   8BB4BB 14040000  MOV ESI,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468B03   8B4E 30          MOV ECX,DWORD PTR DS:[ESI+0x30]
 *  00468B06   2B4E 2C          SUB ECX,DWORD PTR DS:[ESI+0x2C]
 *  00468B09   B8 ABAAAA2A      MOV EAX,0x2AAAAAAB
 *  00468B0E   F7E9             IMUL ECX
 *  00468B10   C1FA 02          SAR EDX,0x2
 *  00468B13   8BC2             MOV EAX,EDX
 *  00468B15   C1E8 1F          SHR EAX,0x1F
 *  00468B18   8D5402 FF        LEA EDX,DWORD PTR DS:[EDX+EAX-0x1]
 *  00468B1C   8995 24FFFFFF    MOV DWORD PTR SS:[EBP-0xDC],EDX
 *  00468B22   85D2             TEST EDX,EDX
 *  00468B24   79 05            JNS SHORT .00468B2B
 *  00468B26   8D46 1C          LEA EAX,DWORD PTR DS:[ESI+0x1C]
 *  00468B29   EB 10            JMP SHORT .00468B3B
 *  00468B2B   8B85 24FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xDC]
 *  00468B31   8B56 2C          MOV EDX,DWORD PTR DS:[ESI+0x2C]
 *  00468B34   8D0C40           LEA ECX,DWORD PTR DS:[EAX+EAX*2]
 *  00468B37   8D44CA 04        LEA EAX,DWORD PTR DS:[EDX+ECX*8+0x4]
 *  00468B3B   8B08             MOV ECX,DWORD PTR DS:[EAX]
 *  00468B3D   8B50 04          MOV EDX,DWORD PTR DS:[EAX+0x4]
 *  00468B40   8B84BB 14040000  MOV EAX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468B47   898D 14FFFFFF    MOV DWORD PTR SS:[EBP-0xEC],ECX
 *  00468B4D   8B48 30          MOV ECX,DWORD PTR DS:[EAX+0x30]
 *  00468B50   2B48 2C          SUB ECX,DWORD PTR DS:[EAX+0x2C]
 *  00468B53   8995 18FFFFFF    MOV DWORD PTR SS:[EBP-0xE8],EDX
 *  00468B59   B8 ABAAAA2A      MOV EAX,0x2AAAAAAB
 *  00468B5E   F7E9             IMUL ECX
 *  00468B60   C1FA 02          SAR EDX,0x2
 *  00468B63   8BC2             MOV EAX,EDX
 *  00468B65   C1E8 1F          SHR EAX,0x1F
 *  00468B68   8D4402 FF        LEA EAX,DWORD PTR DS:[EDX+EAX-0x1]
 *  00468B6C   8983 74050000    MOV DWORD PTR DS:[EBX+0x574],EAX
 *  00468B72   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468B79   8981 84000000    MOV DWORD PTR DS:[ECX+0x84],EAX
 *  00468B7F   8B8D F8FEFFFF    MOV ECX,DWORD PTR SS:[EBP-0x108]
 *  00468B85   8039 00          CMP BYTE PTR DS:[ECX],0x0
 *  00468B88   0F84 CB080000    JE .00469459
 *  00468B8E   8BFF             MOV EDI,EDI
 *  00468B90   8B84BB 14040000  MOV EAX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468B97   8B40 30          MOV EAX,DWORD PTR DS:[EAX+0x30]
 *  00468B9A   8B8D 44FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xBC]
 *  00468BA0   8D70 EC          LEA ESI,DWORD PTR DS:[EAX-0x14]
 *  00468BA3   8A01             MOV AL,BYTE PTR DS:[ECX]
 *  00468BA5   89B5 40FFFFFF    MOV DWORD PTR SS:[EBP-0xC0],ESI
 *  00468BAB   3C 20            CMP AL,0x20
 *  00468BAD   72 04            JB SHORT .00468BB3
 *  00468BAF   3C 7F            CMP AL,0x7F
 *  00468BB1   72 36            JB SHORT .00468BE9
 *  00468BB3   8D50 60          LEA EDX,DWORD PTR DS:[EAX+0x60]
 *  00468BB6   80FA 3F          CMP DL,0x3F
 *  00468BB9   76 2E            JBE SHORT .00468BE9
 *  00468BBB   3C 80            CMP AL,0x80
 *  00468BBD   72 2A            JB SHORT .00468BE9
 *  00468BBF   66:8B01          MOV AX,WORD PTR DS:[ECX]
 *  00468BC2   66:8985 54FFFFFF MOV WORD PTR SS:[EBP-0xAC],AX
 *  00468BC9   8A85 54FFFFFF    MOV AL,BYTE PTR SS:[EBP-0xAC]
 *  00468BCF   3C 20            CMP AL,0x20
 *  00468BD1   72 04            JB SHORT .00468BD7
 *  00468BD3   3C 7F            CMP AL,0x7F
 *  00468BD5   72 18            JB SHORT .00468BEF
 *  00468BD7   04 60            ADD AL,0x60
 *  00468BD9   3C 3F            CMP AL,0x3F
 *  00468BDB   76 12            JBE SHORT .00468BEF
 *  00468BDD   C785 48FFFFFF 02>MOV DWORD PTR SS:[EBP-0xB8],0x2
 *  00468BE7   EB 17            JMP SHORT .00468C00
 *  00468BE9   8885 54FFFFFF    MOV BYTE PTR SS:[EBP-0xAC],AL
 *  00468BEF   C685 55FFFFFF 00 MOV BYTE PTR SS:[EBP-0xAB],0x0
 *  00468BF6   C785 48FFFFFF 01>MOV DWORD PTR SS:[EBP-0xB8],0x1
 *  00468C00   8D85 54FFFFFF    LEA EAX,DWORD PTR SS:[EBP-0xAC]
 *  00468C06   8D50 01          LEA EDX,DWORD PTR DS:[EAX+0x1]
 *  00468C09   8DA424 00000000  LEA ESP,DWORD PTR SS:[ESP]
 *  00468C10   8A08             MOV CL,BYTE PTR DS:[EAX]
 *  00468C12   40               INC EAX
 *  00468C13   84C9             TEST CL,CL
 *  00468C15  ^75 F9            JNZ SHORT .00468C10
 *  00468C17   2BC2             SUB EAX,EDX
 *  00468C19   8D8D 2CFFFFFF    LEA ECX,DWORD PTR SS:[EBP-0xD4]
 *  00468C1F   51               PUSH ECX
 *  00468C20   50               PUSH EAX
 *  00468C21   8B83 54040000    MOV EAX,DWORD PTR DS:[EBX+0x454]
 *  00468C27   8D95 54FFFFFF    LEA EDX,DWORD PTR SS:[EBP-0xAC]
 *  00468C2D   52               PUSH EDX
 *  00468C2E   50               PUSH EAX
 *  00468C2F   FF15 74406100    CALL DWORD PTR DS:[0x614074]             ; gdi32.GetTextExtentPoint32A
 *  00468C35   8B4E 04          MOV ECX,DWORD PTR DS:[ESI+0x4]
 *  00468C38   038D 30FFFFFF    ADD ECX,DWORD PTR SS:[EBP-0xD0]
 *  00468C3E   8B16             MOV EDX,DWORD PTR DS:[ESI]
 *  00468C40   0395 2CFFFFFF    ADD EDX,DWORD PTR SS:[EBP-0xD4]
 *  00468C46   8D46 04          LEA EAX,DWORD PTR DS:[ESI+0x4]
 *  00468C49   51               PUSH ECX
 *  00468C4A   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468C51   52               PUSH EDX
 *  00468C52   8985 50FFFFFF    MOV DWORD PTR SS:[EBP-0xB0],EAX
 *  00468C58   E8 D39A0000      CALL .00472730
 *  00468C5D   83BB D0130300 00 CMP DWORD PTR DS:[EBX+0x313D0],0x0
 *  00468C64   74 34            JE SHORT .00468C9A
 *  00468C66   0FBF83 EA130300  MOVSX EAX,WORD PTR DS:[EBX+0x313EA]
 *  00468C6D   8B8D 50FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xB0]
 *  00468C73   0301             ADD EAX,DWORD PTR DS:[ECX]
 *  00468C75   B9 03000000      MOV ECX,0x3
 *  00468C7A   2B8D 48FFFFFF    SUB ECX,DWORD PTR SS:[EBP-0xB8]
 *  00468C80   50               PUSH EAX
 *  00468C81   0FBF83 E8130300  MOVSX EAX,WORD PTR DS:[EBX+0x313E8]
 *  00468C88   99               CDQ
 *  00468C89   F7F9             IDIV ECX
 *  00468C8B   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468C92   0306             ADD EAX,DWORD PTR DS:[ESI]
 *  00468C94   50               PUSH EAX
 *  00468C95   E8 969A0000      CALL .00472730
 *  00468C9A   A8 01            TEST AL,0x1
 *  00468C9C   0F84 DF020000    JE .00468F81
 *  00468CA2   83BB 7C050000 01 CMP DWORD PTR DS:[EBX+0x57C],0x1
 *  00468CA9   0F85 DA020000    JNZ .00468F89
 *  00468CAF   8D95 54FFFFFF    LEA EDX,DWORD PTR SS:[EBP-0xAC]
 *  00468CB5   52               PUSH EDX
 *  00468CB6   8BCB             MOV ECX,EBX
 *  00468CB8   E8 9309FFFF      CALL .00459650
 *  00468CBD   85C0             TEST EAX,EAX
 *  00468CBF   0F85 C4020000    JNZ .00468F89
 *  00468CC5   8BB5 44FFFFFF    MOV ESI,DWORD PTR SS:[EBP-0xBC]
 *  00468CCB   2BB5 3CFFFFFF    SUB ESI,DWORD PTR SS:[EBP-0xC4]
 *  00468CD1   8D46 01          LEA EAX,DWORD PTR DS:[ESI+0x1]
 *  00468CD4   50               PUSH EAX
 *  00468CD5   89B5 34FFFFFF    MOV DWORD PTR SS:[EBP-0xCC],ESI
 *  00468CDB   8985 4CFFFFFF    MOV DWORD PTR SS:[EBP-0xB4],EAX
 *  00468CE1   E8 32A01800      CALL .005F2D18
 *  00468CE6   8B8D 4CFFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xB4]
 *  00468CEC   56               PUSH ESI
 *  00468CED   8BB5 3CFFFFFF    MOV ESI,DWORD PTR SS:[EBP-0xC4]
 *  00468CF3   56               PUSH ESI
 *  00468CF4   51               PUSH ECX
 *  00468CF5   50               PUSH EAX
 *  00468CF6   8985 50FFFFFF    MOV DWORD PTR SS:[EBP-0xB0],EAX
 *  00468CFC   E8 8CD11800      CALL .005F5E8D
 *  00468D01   8B95 50FFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xB0]
 *  00468D07   8B85 44FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xBC]
 *  00468D0D   2BD6             SUB EDX,ESI
 *  00468D0F   C60402 00        MOV BYTE PTR DS:[EDX+EAX],0x0
 *  00468D13   8BB4BB 14040000  MOV ESI,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468D1A   8B4E 30          MOV ECX,DWORD PTR DS:[ESI+0x30]
 *  00468D1D   2B4E 2C          SUB ECX,DWORD PTR DS:[ESI+0x2C]
 *  00468D20   B8 ABAAAA2A      MOV EAX,0x2AAAAAAB
 *  00468D25   F7E9             IMUL ECX
 *  00468D27   C1FA 02          SAR EDX,0x2
 *  00468D2A   8BCA             MOV ECX,EDX
 *  00468D2C   C1E9 1F          SHR ECX,0x1F
 *  00468D2F   8D540A FE        LEA EDX,DWORD PTR DS:[EDX+ECX-0x2]
 *  00468D33   83C4 14          ADD ESP,0x14
 *  00468D36   85D2             TEST EDX,EDX
 *  00468D38   79 05            JNS SHORT .00468D3F
 *  00468D3A   8D46 1C          LEA EAX,DWORD PTR DS:[ESI+0x1C]
 *  00468D3D   EB 0A            JMP SHORT .00468D49
 *  00468D3F   8B4E 2C          MOV ECX,DWORD PTR DS:[ESI+0x2C]
 *  00468D42   8D0452           LEA EAX,DWORD PTR DS:[EDX+EDX*2]
 *  00468D45   8D44C1 04        LEA EAX,DWORD PTR DS:[ECX+EAX*8+0x4]
 *  00468D49   8B40 08          MOV EAX,DWORD PTR DS:[EAX+0x8]
 *  00468D4C   8985 1CFFFFFF    MOV DWORD PTR SS:[EBP-0xE4],EAX
 *  00468D52   8B84BB 14040000  MOV EAX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468D59   85D2             TEST EDX,EDX
 *  00468D5B   79 05            JNS SHORT .00468D62
 *  00468D5D   83C0 1C          ADD EAX,0x1C
 *  00468D60   EB 0A            JMP SHORT .00468D6C
 *  00468D62   8D0C52           LEA ECX,DWORD PTR DS:[EDX+EDX*2]
 *  00468D65   8B50 2C          MOV EDX,DWORD PTR DS:[EAX+0x2C]
 *  00468D68   8D44CA 04        LEA EAX,DWORD PTR DS:[EDX+ECX*8+0x4]
 *  00468D6C   8B75 14          MOV ESI,DWORD PTR SS:[EBP+0x14]
 *  00468D6F   8B40 0C          MOV EAX,DWORD PTR DS:[EAX+0xC]
 *  00468D72   8985 20FFFFFF    MOV DWORD PTR SS:[EBP-0xE0],EAX
 *  00468D78   85F6             TEST ESI,ESI
 *  00468D7A   78 1E            JS SHORT .00468D9A
 *  00468D7C   8B8D 50FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xB0]
 *  00468D82   8B93 D4130300    MOV EDX,DWORD PTR DS:[EBX+0x313D4]
 *  00468D88   51               PUSH ECX
 *  00468D89   52               PUSH EDX
 *  00468D8A   8D85 14FFFFFF    LEA EAX,DWORD PTR SS:[EBP-0xEC]
 *  00468D90   50               PUSH EAX
 *  00468D91   56               PUSH ESI
 *  00468D92   57               PUSH EDI
 *  00468D93   8BCB             MOV ECX,EBX
 *  00468D95   E8 46D4FFFF      CALL .004661E0
 *  00468D9A   8B8B 6C050000    MOV ECX,DWORD PTR DS:[EBX+0x56C]
 *  00468DA0   8B93 68050000    MOV EDX,DWORD PTR DS:[EBX+0x568]
 *  00468DA6   8B83 94550300    MOV EAX,DWORD PTR DS:[EBX+0x35594]
 *  00468DAC   51               PUSH ECX
 *  00468DAD   52               PUSH EDX
 *  00468DAE   50               PUSH EAX
 *  00468DAF   83EC 1C          SUB ESP,0x1C
 *  00468DB2   8BCC             MOV ECX,ESP
 *  00468DB4   89A5 28FFFFFF    MOV DWORD PTR SS:[EBP-0xD8],ESP
 *  00468DBA   6A FF            PUSH -0x1
 *  00468DBC   6A 00            PUSH 0x0
 *  00468DBE   8D83 AC550300    LEA EAX,DWORD PTR DS:[EBX+0x355AC]
 *  00468DC4   C741 14 0F000000 MOV DWORD PTR DS:[ECX+0x14],0xF
 *  00468DCB   C741 10 00000000 MOV DWORD PTR DS:[ECX+0x10],0x0
 *  00468DD2   50               PUSH EAX
 *  00468DD3   C601 00          MOV BYTE PTR DS:[ECX],0x0
 *  00468DD6   E8 252DFAFF      CALL .0040BB00
 *  00468DDB   C645 FC 05       MOV BYTE PTR SS:[EBP-0x4],0x5
 *  00468DDF   8B8B 54050000    MOV ECX,DWORD PTR DS:[EBX+0x554]
 *  00468DE5   8B93 58050000    MOV EDX,DWORD PTR DS:[EBX+0x558]
 *  00468DEB   8B83 50050000    MOV EAX,DWORD PTR DS:[EBX+0x550]
 *  00468DF1   51               PUSH ECX
 *  00468DF2   8B8D 50FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xB0]
 *  00468DF8   52               PUSH EDX
 *  00468DF9   8B93 5C050000    MOV EDX,DWORD PTR DS:[EBX+0x55C]
 *  00468DFF   50               PUSH EAX
 *  00468E00   8B83 D4130300    MOV EAX,DWORD PTR DS:[EBX+0x313D4]
 *  00468E06   51               PUSH ECX
 *  00468E07   52               PUSH EDX
 *  00468E08   50               PUSH EAX
 *  00468E09   8D8D 14FFFFFF    LEA ECX,DWORD PTR SS:[EBP-0xEC]
 *  00468E0F   51               PUSH ECX
 *  00468E10   56               PUSH ESI
 *  00468E11   C645 FC 01       MOV BYTE PTR SS:[EBP-0x4],0x1
 *  00468E15   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468E1C   E8 CF32FFFF      CALL .0045C0F0
 *  00468E21   83BD FCFEFFFF 00 CMP DWORD PTR SS:[EBP-0x104],0x0
 *  00468E28   0F84 CF000000    JE .00468EFD
 *  00468E2E   8B85 3CFFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xC4]
 *  00468E34   8D50 01          LEA EDX,DWORD PTR DS:[EAX+0x1]
 *  00468E37   8A08             MOV CL,BYTE PTR DS:[EAX]
 *  00468E39   40               INC EAX
 *  00468E3A   84C9             TEST CL,CL
 *  00468E3C  ^75 F9            JNZ SHORT .00468E37
 *  00468E3E   2BC2             SUB EAX,EDX
 *  00468E40   8BF0             MOV ESI,EAX
 *  00468E42   8B85 38FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xC8]
 *  00468E48   8D50 01          LEA EDX,DWORD PTR DS:[EAX+0x1]
 *  00468E4B   EB 03            JMP SHORT .00468E50
 *  00468E4D   8D49 00          LEA ECX,DWORD PTR DS:[ECX]
 *  00468E50   8A08             MOV CL,BYTE PTR DS:[EAX]
 *  00468E52   40               INC EAX
 *  00468E53   84C9             TEST CL,CL
 *  00468E55  ^75 F9            JNZ SHORT .00468E50
 *  00468E57   2BC2             SUB EAX,EDX
 *  00468E59   85F6             TEST ESI,ESI
 *  00468E5B   7E 15            JLE SHORT .00468E72
 *  00468E5D   0FAF85 34FFFFFF  IMUL EAX,DWORD PTR SS:[EBP-0xCC]
 *  00468E64   99               CDQ
 *  00468E65   F7FE             IDIV ESI
 *  00468E67   99               CDQ
 *  00468E68   2BC2             SUB EAX,EDX
 *  00468E6A   8BF0             MOV ESI,EAX
 *  00468E6C   D1FE             SAR ESI,1
 *  00468E6E   03F6             ADD ESI,ESI
 *  00468E70   EB 02            JMP SHORT .00468E74
 *  00468E72   8BF0             MOV ESI,EAX
 *  00468E74   8D46 01          LEA EAX,DWORD PTR DS:[ESI+0x1]
 *  00468E77   50               PUSH EAX
 *  00468E78   E8 9B9E1800      CALL .005F2D18
 *  00468E7D   8B95 38FFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xC8]
 *  00468E83   56               PUSH ESI
 *  00468E84   52               PUSH EDX
 *  00468E85   8D4E 01          LEA ECX,DWORD PTR DS:[ESI+0x1]
 *  00468E88   51               PUSH ECX
 *  00468E89   50               PUSH EAX
 *  00468E8A   8985 4CFFFFFF    MOV DWORD PTR SS:[EBP-0xB4],EAX
 *  00468E90   C60430 00        MOV BYTE PTR DS:[EAX+ESI],0x0
 *  00468E94   E8 F4CF1800      CALL .005F5E8D
 *  00468E99   8B84BB 14040000  MOV EAX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468EA0   8B40 30          MOV EAX,DWORD PTR DS:[EAX+0x30]
 *  00468EA3   01B5 38FFFFFF    ADD DWORD PTR SS:[EBP-0xC8],ESI
 *  00468EA9   C740 E8 01000000 MOV DWORD PTR DS:[EAX-0x18],0x1
 *  00468EB0   8B85 24FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xDC]
 *  00468EB6   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468EBD   83C4 14          ADD ESP,0x14
 *  00468EC0   85C0             TEST EAX,EAX
 *  00468EC2   79 05            JNS SHORT .00468EC9
 *  00468EC4   8D41 1C          LEA EAX,DWORD PTR DS:[ECX+0x1C]
 *  00468EC7   EB 0A            JMP SHORT .00468ED3
 *  00468EC9   8B49 2C          MOV ECX,DWORD PTR DS:[ECX+0x2C]
 *  00468ECC   8D0440           LEA EAX,DWORD PTR DS:[EAX+EAX*2]
 *  00468ECF   8D44C1 04        LEA EAX,DWORD PTR DS:[ECX+EAX*8+0x4]
 *  00468ED3   8B95 1CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xE4]
 *  00468ED9   2B95 14FFFFFF    SUB EDX,DWORD PTR SS:[EBP-0xEC]
 *  00468EDF   8BB5 4CFFFFFF    MOV ESI,DWORD PTR SS:[EBP-0xB4]
 *  00468EE5   50               PUSH EAX
 *  00468EE6   8B45 14          MOV EAX,DWORD PTR SS:[EBP+0x14]
 *  00468EE9   52               PUSH EDX
 *  00468EEA   50               PUSH EAX
 *  00468EEB   56               PUSH ESI
 *  00468EEC   57               PUSH EDI
 *  00468EED   8BCB             MOV ECX,EBX
 *  00468EEF   E8 2C9FFFFF      CALL .00462E20
 *  00468EF4   56               PUSH ESI
 *  00468EF5   E8 F7A71800      CALL .005F36F1
 *  00468EFA   83C4 04          ADD ESP,0x4
 *  00468EFD   8B8D 50FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xB0]
 *  00468F03   51               PUSH ECX
 *  00468F04   E8 E8A71800      CALL .005F36F1
 *  00468F09   8B93 D4130300    MOV EDX,DWORD PTR DS:[EBX+0x313D4]
 *  00468F0F   83C4 04          ADD ESP,0x4
 *  00468F12   52               PUSH EDX
 *  00468F13   8BCB             MOV ECX,EBX
 *  00468F15   E8 46E9FAFF      CALL .00417860
 *  00468F1A   8B45 14          MOV EAX,DWORD PTR SS:[EBP+0x14]
 *  00468F1D   50               PUSH EAX
 *  00468F1E   57               PUSH EDI
 *  00468F1F   8BCB             MOV ECX,EBX
 *  00468F21   E8 AAEDFFFF      CALL .00467CD0
 *  00468F26   8B84BB 14040000  MOV EAX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00468F2D   8B70 30          MOV ESI,DWORD PTR DS:[EAX+0x30]
 *  00468F30   8B4E EC          MOV ECX,DWORD PTR DS:[ESI-0x14]
 *  00468F33   83C6 EC          ADD ESI,-0x14
 *  00468F36   8B56 04          MOV EDX,DWORD PTR DS:[ESI+0x4]
 *  00468F39   898D 14FFFFFF    MOV DWORD PTR SS:[EBP-0xEC],ECX
 *  00468F3F   8D4E 04          LEA ECX,DWORD PTR DS:[ESI+0x4]
 *  00468F42   898D 50FFFFFF    MOV DWORD PTR SS:[EBP-0xB0],ECX
 *  00468F48   8B8D 44FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xBC]
 *  00468F4E   898D 3CFFFFFF    MOV DWORD PTR SS:[EBP-0xC4],ECX
 *  00468F54   8B48 30          MOV ECX,DWORD PTR DS:[EAX+0x30]
 *  00468F57   2B48 2C          SUB ECX,DWORD PTR DS:[EAX+0x2C]
 *  00468F5A   8995 18FFFFFF    MOV DWORD PTR SS:[EBP-0xE8],EDX
 *  00468F60   B8 ABAAAA2A      MOV EAX,0x2AAAAAAB
 *  00468F65   F7E9             IMUL ECX
 *  00468F67   C1FA 02          SAR EDX,0x2
 *  00468F6A   8BC2             MOV EAX,EDX
 *  00468F6C   C1E8 1F          SHR EAX,0x1F
 *  00468F6F   8D4C02 FF        LEA ECX,DWORD PTR DS:[EDX+EAX-0x1]
 *  00468F73   89B5 40FFFFFF    MOV DWORD PTR SS:[EBP-0xC0],ESI
 *  00468F79   898D 24FFFFFF    MOV DWORD PTR SS:[EBP-0xDC],ECX
 *  00468F7F   EB 08            JMP SHORT .00468F89
 *  00468F81   A8 02            TEST AL,0x2
 *  00468F83   0F85 AB040000    JNZ .00469434
 *  00468F89   8B16             MOV EDX,DWORD PTR DS:[ESI]
 *  00468F8B   8B85 50FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xB0]
 *  00468F91   8B08             MOV ECX,DWORD PTR DS:[EAX]
 *  00468F93   8B83 54040000    MOV EAX,DWORD PTR DS:[EBX+0x454]
 *  00468F99   8995 F4FEFFFF    MOV DWORD PTR SS:[EBP-0x10C],EDX
 *  00468F9F   8D95 58FFFFFF    LEA EDX,DWORD PTR SS:[EBP-0xA8]
 *  00468FA5   52               PUSH EDX
 *  00468FA6   50               PUSH EAX
 *  00468FA7   898D 28FFFFFF    MOV DWORD PTR SS:[EBP-0xD8],ECX
 *  00468FAD   FF15 30406100    CALL DWORD PTR DS:[0x614030]             ; gdi32.GetTextMetricsA
 *  00468FB3   8B95 2CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xD4]
 *  00468FB9   8B0E             MOV ECX,DWORD PTR DS:[ESI]
 *  00468FBB   8D0411           LEA EAX,DWORD PTR DS:[ECX+EDX]
 *  00468FBE   8946 08          MOV DWORD PTR DS:[ESI+0x8],EAX
 *  00468FC1   8B85 50FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xB0]
 *  00468FC7   8B00             MOV EAX,DWORD PTR DS:[EAX]
 *  00468FC9   0383 D4130300    ADD EAX,DWORD PTR DS:[EBX+0x313D4]
 *  00468FCF   8946 0C          MOV DWORD PTR DS:[ESI+0xC],EAX
 *  00468FD2   83BB 5C050000 00 CMP DWORD PTR DS:[EBX+0x55C],0x0
 *  00468FD9   74 0B            JE SHORT .00468FE6
 *  00468FDB   8B93 6C050000    MOV EDX,DWORD PTR DS:[EBX+0x56C]
 *  00468FE1   03D0             ADD EDX,EAX
 *  00468FE3   8956 0C          MOV DWORD PTR DS:[ESI+0xC],EDX
 *  00468FE6   83BB D0130300 00 CMP DWORD PTR DS:[EBX+0x313D0],0x0
 *  00468FED   74 2E            JE SHORT .0046901D
 *  00468FEF   8B83 0C040000    MOV EAX,DWORD PTR DS:[EBX+0x40C]
 *  00468FF5   83B8 8C040000 02 CMP DWORD PTR DS:[EAX+0x48C],0x2
 *  00468FFC   74 1F            JE SHORT .0046901D
 *  00468FFE   0FBF83 E8130300  MOVSX EAX,WORD PTR DS:[EBX+0x313E8]
 *  00469005   B9 03000000      MOV ECX,0x3
 *  0046900A   2B8D 48FFFFFF    SUB ECX,DWORD PTR SS:[EBP-0xB8]
 *  00469010   99               CDQ
 *  00469011   F7F9             IDIV ECX
 *  00469013   0306             ADD EAX,DWORD PTR DS:[ESI]
 *  00469015   8946 08          MOV DWORD PTR DS:[ESI+0x8],EAX
 *  00469018   E9 77000000      JMP .00469094
 *  0046901D   8B93 0C040000    MOV EDX,DWORD PTR DS:[EBX+0x40C]
 *  00469023   83BA 8C040000 02 CMP DWORD PTR DS:[EDX+0x48C],0x2
 *  0046902A   75 5F            JNZ SHORT .0046908B
 *  0046902C   8B83 38140300    MOV EAX,DWORD PTR DS:[EBX+0x31438]
 *  00469032   8B8B 54040000    MOV ECX,DWORD PTR DS:[EBX+0x454]
 *  00469038   50               PUSH EAX
 *  00469039   51               PUSH ECX
 *  0046903A   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  00469040   8985 4CFFFFFF    MOV DWORD PTR SS:[EBP-0xB4],EAX
 *  00469046   8D85 54FFFFFF    LEA EAX,DWORD PTR SS:[EBP-0xAC]
 *  0046904C   8D50 01          LEA EDX,DWORD PTR DS:[EAX+0x1]
 *  0046904F   90               NOP
 *  00469050   8A08             MOV CL,BYTE PTR DS:[EAX]
 *  00469052   40               INC EAX
 *  00469053   84C9             TEST CL,CL
 *  00469055  ^75 F9            JNZ SHORT .00469050
 *  00469057   8B8B 54040000    MOV ECX,DWORD PTR DS:[EBX+0x454]
 *  0046905D   2BC2             SUB EAX,EDX
 *  0046905F   8D95 2CFFFFFF    LEA EDX,DWORD PTR SS:[EBP-0xD4]
 *  00469065   52               PUSH EDX
 *  00469066   50               PUSH EAX
 *  00469067   8D85 54FFFFFF    LEA EAX,DWORD PTR SS:[EBP-0xAC]
 *  0046906D   50               PUSH EAX
 *  0046906E   51               PUSH ECX
 *  0046906F   FF15 74406100    CALL DWORD PTR DS:[0x614074]             ; gdi32.GetTextExtentPoint32A
 *  00469075   8B95 4CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xB4]
 *  0046907B   8B83 54040000    MOV EAX,DWORD PTR DS:[EBX+0x454]
 *  00469081   52               PUSH EDX
 *  00469082   50               PUSH EAX
 *  00469083   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  00469089   8B0E             MOV ECX,DWORD PTR DS:[ESI]
 *  0046908B   038D 2CFFFFFF    ADD ECX,DWORD PTR SS:[EBP-0xD4]
 *  00469091   894E 08          MOV DWORD PTR DS:[ESI+0x8],ECX
 *  00469094   8B83 54040000    MOV EAX,DWORD PTR DS:[EBX+0x454]
 *  0046909A   6A 06            PUSH 0x6
 *  0046909C   50               PUSH EAX
 *  0046909D   FF15 24406100    CALL DWORD PTR DS:[0x614024]             ; gdi32.GetCurrentObject
 *  004690A3   83BD 48FFFFFF 01 CMP DWORD PTR SS:[EBP-0xB8],0x1
 *  004690AA   8985 4CFFFFFF    MOV DWORD PTR SS:[EBP-0xB4],EAX
 *  004690B0   C785 34FFFFFF 00>MOV DWORD PTR SS:[EBP-0xCC],0x0
 *  004690BA   75 3A            JNZ SHORT .004690F6
 *  004690BC   66:0FBE95 54FFFF>MOVSX DX,BYTE PTR SS:[EBP-0xAC]
 *  004690C4   8D8D 34FFFFFF    LEA ECX,DWORD PTR SS:[EBP-0xCC]
 *  004690CA   51               PUSH ECX
 *  004690CB   0FB7C2           MOVZX EAX,DX
 *  004690CE   50               PUSH EAX
 *  004690CF   83EC 3C          SUB ESP,0x3C
 *  004690D2   8BFC             MOV EDI,ESP
 *  004690D4   8DB3 D0040000    LEA ESI,DWORD PTR DS:[EBX+0x4D0]
 *  004690DA   B9 0F000000      MOV ECX,0xF
 *  004690DF   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
 *  004690E1   8BCB             MOV ECX,EBX
 *  004690E3   E8 58D4FEFF      CALL .00456540
 *  004690E8   8BBD 10FFFFFF    MOV EDI,DWORD PTR SS:[EBP-0xF0]
 *  004690EE   8BB5 40FFFFFF    MOV ESI,DWORD PTR SS:[EBP-0xC0]
 *  004690F4   EB 42            JMP SHORT .00469138
 *  004690F6   8B8B 10040000    MOV ECX,DWORD PTR DS:[EBX+0x410]
 *  004690FC   83B9 44B60000 00 CMP DWORD PTR DS:[ECX+0xB644],0x0
 *  00469103   75 1F            JNZ SHORT .00469124
 *  00469105   8B93 0C040000    MOV EDX,DWORD PTR DS:[EBX+0x40C]
 *  0046910B   83BA 8C040000 02 CMP DWORD PTR DS:[EDX+0x48C],0x2
 *  00469112   75 10            JNZ SHORT .00469124
 *  00469114   8B83 4C040000    MOV EAX,DWORD PTR DS:[EBX+0x44C]
 *  0046911A   8B8B 54040000    MOV ECX,DWORD PTR DS:[EBX+0x454]
 *  00469120   50               PUSH EAX
 *  00469121   51               PUSH ECX
 *  00469122   EB 0E            JMP SHORT .00469132
 *  00469124   8B93 3C040000    MOV EDX,DWORD PTR DS:[EBX+0x43C]
 *  0046912A   8B83 54040000    MOV EAX,DWORD PTR DS:[EBX+0x454]
 *  00469130   52               PUSH EDX
 *  00469131   50               PUSH EAX
 *  00469132   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  00469138   8B93 54040000    MOV EDX,DWORD PTR DS:[EBX+0x454]
 *  0046913E   8D8D 58FFFFFF    LEA ECX,DWORD PTR SS:[EBP-0xA8]
 *  00469144   51               PUSH ECX
 *  00469145   52               PUSH EDX
 *  00469146   FF15 30406100    CALL DWORD PTR DS:[0x614030]             ; gdi32.GetTextMetricsA
 *  0046914C   D983 E0550300    FLD DWORD PTR DS:[EBX+0x355E0]
 *  00469152   DA0E             FIMUL DWORD PTR DS:[ESI]
 *  00469154   DD05 78466100    FLD QWORD PTR DS:[0x614678]
 *  0046915A   DCC1             FADD ST(1),ST
 *  0046915C   D9C9             FXCH ST(1)
 *  0046915E   E8 6DAF1800      CALL .005F40D0
 *  00469163   8985 00FFFFFF    MOV DWORD PTR SS:[EBP-0x100],EAX
 *  00469169   8B85 50FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xB0]
 *  0046916F   DB00             FILD DWORD PTR DS:[EAX]
 *  00469171   D88B E4550300    FMUL DWORD PTR DS:[EBX+0x355E4]
 *  00469177   D8C1             FADD ST,ST(1)
 *  00469179   E8 52AF1800      CALL .005F40D0
 *  0046917E   83BB D0130300 00 CMP DWORD PTR DS:[EBX+0x313D0],0x0
 *  00469185   8985 04FFFFFF    MOV DWORD PTR SS:[EBP-0xFC],EAX
 *  0046918B   75 1E            JNZ SHORT .004691AB
 *  0046918D   8B8B 10040000    MOV ECX,DWORD PTR DS:[EBX+0x410]
 *  00469193   83B9 44B60000 00 CMP DWORD PTR DS:[ECX+0xB644],0x0
 *  0046919A   75 0F            JNZ SHORT .004691AB
 *  0046919C   8B93 0C040000    MOV EDX,DWORD PTR DS:[EBX+0x40C]
 *  004691A2   83BA 8C040000 02 CMP DWORD PTR DS:[EDX+0x48C],0x2
 *  004691A9   74 6B            JE SHORT .00469216
 *  004691AB   DB85 5CFFFFFF    FILD DWORD PTR SS:[EBP-0xA4]
 *  004691B1   DB83 F0130300    FILD DWORD PTR DS:[EBX+0x313F0]
 *  004691B7   D88B E4550300    FMUL DWORD PTR DS:[EBX+0x355E4]
 *  004691BD   DEC2             FADDP ST(2),ST
 *  004691BF   DEE1             FSUBRP ST(1),ST
 *  004691C1   E8 0AAF1800      CALL .005F40D0
 *  004691C6   8985 40FFFFFF    MOV DWORD PTR SS:[EBP-0xC0],EAX
 *  004691CC   8B85 5CFFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xA4]
 *  004691D2   2B83 30140300    SUB EAX,DWORD PTR DS:[EBX+0x31430]
 *  004691D8   8985 F0FEFFFF    MOV DWORD PTR SS:[EBP-0x110],EAX
 *  004691DE   DB85 F0FEFFFF    FILD DWORD PTR SS:[EBP-0x110]
 *  004691E4   D8A3 E4550300    FSUB DWORD PTR DS:[EBX+0x355E4]
 *  004691EA   E8 E1AE1800      CALL .005F40D0
 *  004691EF   83BD 40FFFFFF 00 CMP DWORD PTR SS:[EBP-0xC0],0x0
 *  004691F6   74 10            JE SHORT .00469208
 *  004691F8   3985 40FFFFFF    CMP DWORD PTR SS:[EBP-0xC0],EAX
 *  004691FE   7D 08            JGE SHORT .00469208
 *  00469200   2985 04FFFFFF    SUB DWORD PTR SS:[EBP-0xFC],EAX
 *  00469206   EB 10            JMP SHORT .00469218
 *  00469208   8B8D 40FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xC0]
 *  0046920E   298D 04FFFFFF    SUB DWORD PTR SS:[EBP-0xFC],ECX
 *  00469214   EB 02            JMP SHORT .00469218
 *  00469216   DDD8             FSTP ST
 *  00469218   83BB 48050000 00 CMP DWORD PTR DS:[EBX+0x548],0x0
 *  0046921F   6A 01            PUSH 0x1
 *  00469221   74 5F            JE SHORT .00469282
 *  00469223   8B83 5C050000    MOV EAX,DWORD PTR DS:[EBX+0x55C]
 *  00469229   8B8B 8C550300    MOV ECX,DWORD PTR DS:[EBX+0x3558C]
 *  0046922F   8D95 54FFFFFF    LEA EDX,DWORD PTR SS:[EBP-0xAC]
 *  00469235   85C0             TEST EAX,EAX
 *  00469237   74 25            JE SHORT .0046925E
 *  00469239   50               PUSH EAX
 *  0046923A   8B85 5CFFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xA4]
 *  00469240   52               PUSH EDX
 *  00469241   8B95 04FFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xFC]
 *  00469247   50               PUSH EAX
 *  00469248   8B85 00FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0x100]
 *  0046924E   51               PUSH ECX
 *  0046924F   52               PUSH EDX
 *  00469250   50               PUSH EAX
 *  00469251   8D4F 14          LEA ECX,DWORD PTR DS:[EDI+0x14]
 *  00469254   51               PUSH ECX
 *  00469255   8BCB             MOV ECX,EBX
 *  00469257   E8 D47A0000      CALL .00470D30
 *  0046925C   EB 5B            JMP SHORT .004692B9
 *  0046925E   8B85 5CFFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xA4]
 *  00469264   52               PUSH EDX
 *  00469265   8B95 04FFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xFC]
 *  0046926B   50               PUSH EAX
 *  0046926C   8B85 00FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0x100]
 *  00469272   51               PUSH ECX
 *  00469273   52               PUSH EDX
 *  00469274   50               PUSH EAX
 *  00469275   8D4F 14          LEA ECX,DWORD PTR DS:[EDI+0x14]
 *  00469278   51               PUSH ECX
 *  00469279   8BCB             MOV ECX,EBX
 *  0046927B   E8 30320000      CALL .0046C4B0
 *  00469280   EB 37            JMP SHORT .004692B9
 *  00469282   8B8B 5C050000    MOV ECX,DWORD PTR DS:[EBX+0x55C]
 *  00469288   8B93 54050000    MOV EDX,DWORD PTR DS:[EBX+0x554]
 *  0046928E   8B83 50050000    MOV EAX,DWORD PTR DS:[EBX+0x550]
 *  00469294   6A 00            PUSH 0x0
 *  00469296   51               PUSH ECX
 *  00469297   52               PUSH EDX
 *  00469298   8B95 04FFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xFC]
 *  0046929E   50               PUSH EAX
 *  0046929F   8B85 00FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0x100]
 *  004692A5   8D8D 54FFFFFF    LEA ECX,DWORD PTR SS:[EBP-0xAC]
 *  004692AB   51               PUSH ECX
 *  004692AC   52               PUSH EDX
 *  004692AD   50               PUSH EAX
 *  004692AE   8D4F 14          LEA ECX,DWORD PTR DS:[EDI+0x14]
 *  004692B1   51               PUSH ECX
 *  004692B2   8BCB             MOV ECX,EBX
 *  004692B4   E8 A7AEFEFF      CALL .00454160
 *  004692B9   8B95 4CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xB4]
 *  004692BF   8B83 54040000    MOV EAX,DWORD PTR DS:[EBX+0x454]
 *  004692C5   52               PUSH EDX
 *  004692C6   50               PUSH EAX
 *  004692C7   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  004692CD   8B85 48FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xB8]
 *  004692D3   0185 44FFFFFF    ADD DWORD PTR SS:[EBP-0xBC],EAX
 *  004692D9   83F8 01          CMP EAX,0x1
 *  004692DC   75 1B            JNZ SHORT .004692F9
 *  004692DE   8B8B 3C040000    MOV ECX,DWORD PTR DS:[EBX+0x43C]
 *  004692E4   8B93 54040000    MOV EDX,DWORD PTR DS:[EBX+0x454]
 *  004692EA   51               PUSH ECX
 *  004692EB   52               PUSH EDX
 *  004692EC   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  004692F2   8BCB             MOV ECX,EBX
 *  004692F4   E8 27E7FEFF      CALL .00457A20
 *  004692F9   83BD 34FFFFFF 00 CMP DWORD PTR SS:[EBP-0xCC],0x0
 *  00469300   74 0D            JE SHORT .0046930F
 *  00469302   8B85 34FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xCC]
 *  00469308   50               PUSH EAX
 *  00469309   FF15 50406100    CALL DWORD PTR DS:[0x614050]             ; gdi32.DeleteObject
 *  0046930F   8B85 28FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xD8]
 *  00469315   8B8D F4FEFFFF    MOV ECX,DWORD PTR SS:[EBP-0x10C]
 *  0046931B   8B95 50FFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xB0]
 *  00469321   890E             MOV DWORD PTR DS:[ESI],ECX
 *  00469323   8902             MOV DWORD PTR DS:[EDX],EAX
 *  00469325   0383 D4130300    ADD EAX,DWORD PTR DS:[EBX+0x313D4]
 *  0046932B   8946 0C          MOV DWORD PTR DS:[ESI+0xC],EAX
 *  0046932E   83BB 5C050000 00 CMP DWORD PTR DS:[EBX+0x55C],0x0
 *  00469335   74 0B            JE SHORT .00469342
 *  00469337   8B93 6C050000    MOV EDX,DWORD PTR DS:[EBX+0x56C]
 *  0046933D   03D0             ADD EDX,EAX
 *  0046933F   8956 0C          MOV DWORD PTR DS:[ESI+0xC],EDX
 *  00469342   83BB D0130300 00 CMP DWORD PTR DS:[EBX+0x313D0],0x0
 *  00469349   74 2B            JE SHORT .00469376
 *  0046934B   8B83 0C040000    MOV EAX,DWORD PTR DS:[EBX+0x40C]
 *  00469351   83B8 8C040000 02 CMP DWORD PTR DS:[EAX+0x48C],0x2
 *  00469358   74 1C            JE SHORT .00469376
 *  0046935A   0FBF83 E8130300  MOVSX EAX,WORD PTR DS:[EBX+0x313E8]
 *  00469361   BE 03000000      MOV ESI,0x3
 *  00469366   2BB5 48FFFFFF    SUB ESI,DWORD PTR SS:[EBP-0xB8]
 *  0046936C   99               CDQ
 *  0046936D   F7FE             IDIV ESI
 *  0046936F   03C1             ADD EAX,ECX
 *  00469371   E9 78000000      JMP .004693EE
 *  00469376   8B93 0C040000    MOV EDX,DWORD PTR DS:[EBX+0x40C]
 *  0046937C   83BA 8C040000 02 CMP DWORD PTR DS:[EDX+0x48C],0x2
 *  00469383   75 60            JNZ SHORT .004693E5
 *  00469385   8B83 38140300    MOV EAX,DWORD PTR DS:[EBX+0x31438]
 *  0046938B   8B8B 54040000    MOV ECX,DWORD PTR DS:[EBX+0x454]
 *  00469391   50               PUSH EAX
 *  00469392   51               PUSH ECX
 *  00469393   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  00469399   8D85 54FFFFFF    LEA EAX,DWORD PTR SS:[EBP-0xAC]
 *  0046939F   8D50 01          LEA EDX,DWORD PTR DS:[EAX+0x1]
 *  004693A2   8A08             MOV CL,BYTE PTR DS:[EAX]
 *  004693A4   40               INC EAX
 *  004693A5   84C9             TEST CL,CL
 *  004693A7  ^75 F9            JNZ SHORT .004693A2
 *  004693A9   8B8B 54040000    MOV ECX,DWORD PTR DS:[EBX+0x454]
 *  004693AF   2BC2             SUB EAX,EDX
 *  004693B1   8D95 2CFFFFFF    LEA EDX,DWORD PTR SS:[EBP-0xD4]
 *  004693B7   52               PUSH EDX
 *  004693B8   50               PUSH EAX
 *  004693B9   8D85 54FFFFFF    LEA EAX,DWORD PTR SS:[EBP-0xAC]
 *  004693BF   50               PUSH EAX
 *  004693C0   51               PUSH ECX
 *  004693C1   FF15 74406100    CALL DWORD PTR DS:[0x614074]             ; gdi32.GetTextExtentPoint32A
 *  004693C7   8B95 4CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xB4]
 *  004693CD   8B83 54040000    MOV EAX,DWORD PTR DS:[EBX+0x454]
 *  004693D3   52               PUSH EDX
 *  004693D4   50               PUSH EAX
 *  004693D5   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  004693DB   8B06             MOV EAX,DWORD PTR DS:[ESI]
 *  004693DD   0385 2CFFFFFF    ADD EAX,DWORD PTR SS:[EBP-0xD4]
 *  004693E3   EB 09            JMP SHORT .004693EE
 *  004693E5   8B95 2CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xD4]
 *  004693EB   8D0411           LEA EAX,DWORD PTR DS:[ECX+EDX]
 *  004693EE   8B8D 50FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xB0]
 *  004693F4   8B11             MOV EDX,DWORD PTR DS:[ECX]
 *  004693F6   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  004693FD   8945 DC          MOV DWORD PTR SS:[EBP-0x24],EAX
 *  00469400   33C0             XOR EAX,EAX
 *  00469402   8945 E4          MOV DWORD PTR SS:[EBP-0x1C],EAX
 *  00469405   8945 E8          MOV DWORD PTR SS:[EBP-0x18],EAX
 *  00469408   8945 D8          MOV DWORD PTR SS:[EBP-0x28],EAX
 *  0046940B   8955 E0          MOV DWORD PTR SS:[EBP-0x20],EDX
 *  0046940E   8B91 1C010000    MOV EDX,DWORD PTR DS:[ECX+0x11C]
 *  00469414   8D45 D8          LEA EAX,DWORD PTR SS:[EBP-0x28]
 *  00469417   50               PUSH EAX
 *  00469418   83C1 2C          ADD ECX,0x2C
 *  0046941B   8955 EC          MOV DWORD PTR SS:[EBP-0x14],EDX
 *  0046941E   E8 9D15FFFF      CALL .0045A9C0
 *  00469423   8B8D 44FFFFFF    MOV ECX,DWORD PTR SS:[EBP-0xBC]
 *  00469429   8039 00          CMP BYTE PTR DS:[ECX],0x0
 *  0046942C  ^0F85 5EF7FFFF    JNZ .00468B90
 *  00469432   EB 25            JMP SHORT .00469459
 *  00469434   8B95 F8FEFFFF    MOV EDX,DWORD PTR SS:[EBP-0x108]
 *  0046943A   52               PUSH EDX
 *  0046943B   68 A4D76100      PUSH .0061D7A4
 *  00469440   8D73 08          LEA ESI,DWORD PTR DS:[EBX+0x8]
 *  00469443   68 00040000      PUSH 0x400
 *  00469448   56               PUSH ESI
 *  00469449   E8 02E8F9FF      CALL .00407C50
 *  0046944E   83C4 10          ADD ESP,0x10
 *  00469451   56               PUSH ESI
 *  00469452   8BCB             MOV ECX,EBX
 *  00469454   E8 77A0F9FF      CALL .004034D0
 *  00469459   83BB 7C140300 00 CMP DWORD PTR DS:[EBX+0x3147C],0x0
 *  00469460   74 25            JE SHORT .00469487
 *  00469462   8B83 3C040000    MOV EAX,DWORD PTR DS:[EBX+0x43C]
 *  00469468   8B8B 54040000    MOV ECX,DWORD PTR DS:[EBX+0x454]
 *  0046946E   50               PUSH EAX
 *  0046946F   51               PUSH ECX
 *  00469470   FF15 58406100    CALL DWORD PTR DS:[0x614058]             ; gdi32.SelectObject
 *  00469476   8BCB             MOV ECX,EBX
 *  00469478   E8 A3E5FEFF      CALL .00457A20
 *  0046947D   C783 7C140300 00>MOV DWORD PTR DS:[EBX+0x3147C],0x0
 *  00469487   8BB4BB 14040000  MOV ESI,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  0046948E   8B4E 30          MOV ECX,DWORD PTR DS:[ESI+0x30]
 *  00469491   2B4E 2C          SUB ECX,DWORD PTR DS:[ESI+0x2C]
 *  00469494   B8 ABAAAA2A      MOV EAX,0x2AAAAAAB
 *  00469499   F7E9             IMUL ECX
 *  0046949B   C1FA 02          SAR EDX,0x2
 *  0046949E   8BC2             MOV EAX,EDX
 *  004694A0   C1E8 1F          SHR EAX,0x1F
 *  004694A3   8D4402 FE        LEA EAX,DWORD PTR DS:[EDX+EAX-0x2]
 *  004694A7   85C0             TEST EAX,EAX
 *  004694A9   79 05            JNS SHORT .004694B0
 *  004694AB   8D4E 1C          LEA ECX,DWORD PTR DS:[ESI+0x1C]
 *  004694AE   EB 0A            JMP SHORT .004694BA
 *  004694B0   8B56 2C          MOV EDX,DWORD PTR DS:[ESI+0x2C]
 *  004694B3   8D0C40           LEA ECX,DWORD PTR DS:[EAX+EAX*2]
 *  004694B6   8D4CCA 04        LEA ECX,DWORD PTR DS:[EDX+ECX*8+0x4]
 *  004694BA   8B49 08          MOV ECX,DWORD PTR DS:[ECX+0x8]
 *  004694BD   898D 1CFFFFFF    MOV DWORD PTR SS:[EBP-0xE4],ECX
 *  004694C3   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  004694CA   85C0             TEST EAX,EAX
 *  004694CC   79 05            JNS SHORT .004694D3
 *  004694CE   8D41 1C          LEA EAX,DWORD PTR DS:[ECX+0x1C]
 *  004694D1   EB 0A            JMP SHORT .004694DD
 *  004694D3   8D1440           LEA EDX,DWORD PTR DS:[EAX+EAX*2]
 *  004694D6   8B41 2C          MOV EAX,DWORD PTR DS:[ECX+0x2C]
 *  004694D9   8D44D0 04        LEA EAX,DWORD PTR DS:[EAX+EDX*8+0x4]
 *  004694DD   8B75 14          MOV ESI,DWORD PTR SS:[EBP+0x14]
 *  004694E0   8B48 0C          MOV ECX,DWORD PTR DS:[EAX+0xC]
 *  004694E3   898D 20FFFFFF    MOV DWORD PTR SS:[EBP-0xE0],ECX
 *  004694E9   F7C6 00000080    TEST ESI,0x80000000
 *  004694EF   75 1E            JNZ SHORT .0046950F
 *  004694F1   8B95 3CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xC4]
 *  004694F7   8B83 D4130300    MOV EAX,DWORD PTR DS:[EBX+0x313D4]
 *  004694FD   52               PUSH EDX
 *  004694FE   50               PUSH EAX
 *  004694FF   8D8D 14FFFFFF    LEA ECX,DWORD PTR SS:[EBP-0xEC]
 *  00469505   51               PUSH ECX
 *  00469506   56               PUSH ESI
 *  00469507   57               PUSH EDI
 *  00469508   8BCB             MOV ECX,EBX
 *  0046950A   E8 D1CCFFFF      CALL .004661E0
 *  0046950F   8B93 6C050000    MOV EDX,DWORD PTR DS:[EBX+0x56C]
 *  00469515   8B83 68050000    MOV EAX,DWORD PTR DS:[EBX+0x568]
 *  0046951B   8B8B 94550300    MOV ECX,DWORD PTR DS:[EBX+0x35594]
 *  00469521   52               PUSH EDX
 *  00469522   50               PUSH EAX
 *  00469523   51               PUSH ECX
 *  00469524   83EC 1C          SUB ESP,0x1C
 *  00469527   8BCC             MOV ECX,ESP
 *  00469529   89A5 28FFFFFF    MOV DWORD PTR SS:[EBP-0xD8],ESP
 *  0046952F   6A FF            PUSH -0x1
 *  00469531   6A 00            PUSH 0x0
 *  00469533   8D83 AC550300    LEA EAX,DWORD PTR DS:[EBX+0x355AC]
 *  00469539   C741 14 0F000000 MOV DWORD PTR DS:[ECX+0x14],0xF
 *  00469540   C741 10 00000000 MOV DWORD PTR DS:[ECX+0x10],0x0
 *  00469547   50               PUSH EAX
 *  00469548   C601 00          MOV BYTE PTR DS:[ECX],0x0
 *  0046954B   E8 B025FAFF      CALL .0040BB00
 *  00469550   C645 FC 06       MOV BYTE PTR SS:[EBP-0x4],0x6
 *  00469554   8B93 54050000    MOV EDX,DWORD PTR DS:[EBX+0x554]
 *  0046955A   8B83 58050000    MOV EAX,DWORD PTR DS:[EBX+0x558]
 *  00469560   8B8B 50050000    MOV ECX,DWORD PTR DS:[EBX+0x550]
 *  00469566   52               PUSH EDX
 *  00469567   8B95 3CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xC4]
 *  0046956D   50               PUSH EAX
 *  0046956E   8B83 5C050000    MOV EAX,DWORD PTR DS:[EBX+0x55C]
 *  00469574   51               PUSH ECX
 *  00469575   8B8B D4130300    MOV ECX,DWORD PTR DS:[EBX+0x313D4]
 *  0046957B   52               PUSH EDX
 *  0046957C   50               PUSH EAX
 *  0046957D   51               PUSH ECX
 *  0046957E   8D95 14FFFFFF    LEA EDX,DWORD PTR SS:[EBP-0xEC]
 *  00469584   52               PUSH EDX
 *  00469585   56               PUSH ESI
 *  00469586   C645 FC 01       MOV BYTE PTR SS:[EBP-0x4],0x1
 *  0046958A   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  00469591   E8 5A2BFFFF      CALL .0045C0F0
 *  00469596   83BD FCFEFFFF 00 CMP DWORD PTR SS:[EBP-0x104],0x0
 *  0046959D   C783 98550300 00>MOV DWORD PTR DS:[EBX+0x35598],0x0
 *  004695A7   74 4F            JE SHORT .004695F8
 *  004695A9   8B84BB 14040000  MOV EAX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  004695B0   8B40 30          MOV EAX,DWORD PTR DS:[EAX+0x30]
 *  004695B3   C740 E8 01000000 MOV DWORD PTR DS:[EAX-0x18],0x1
 *  004695BA   8B85 24FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xDC]
 *  004695C0   8B8CBB 14040000  MOV ECX,DWORD PTR DS:[EBX+EDI*4+0x414]
 *  004695C7   85C0             TEST EAX,EAX
 *  004695C9   79 05            JNS SHORT .004695D0
 *  004695CB   8D41 1C          LEA EAX,DWORD PTR DS:[ECX+0x1C]
 *  004695CE   EB 0A            JMP SHORT .004695DA
 *  004695D0   8B49 2C          MOV ECX,DWORD PTR DS:[ECX+0x2C]
 *  004695D3   8D0440           LEA EAX,DWORD PTR DS:[EAX+EAX*2]
 *  004695D6   8D44C1 04        LEA EAX,DWORD PTR DS:[ECX+EAX*8+0x4]
 *  004695DA   8B95 1CFFFFFF    MOV EDX,DWORD PTR SS:[EBP-0xE4]
 *  004695E0   2B95 14FFFFFF    SUB EDX,DWORD PTR SS:[EBP-0xEC]
 *  004695E6   50               PUSH EAX
 *  004695E7   8B85 38FFFFFF    MOV EAX,DWORD PTR SS:[EBP-0xC8]
 *  004695ED   52               PUSH EDX
 *  004695EE   56               PUSH ESI
 *  004695EF   50               PUSH EAX
 *  004695F0   57               PUSH EDI
 *  004695F1   8BCB             MOV ECX,EBX
 *  004695F3   E8 2898FFFF      CALL .00462E20
 *  004695F8   C745 FC FFFFFFFF MOV DWORD PTR SS:[EBP-0x4],-0x1
 *  004695FF   B8 01000000      MOV EAX,0x1
 *  00469604   C745 CC 00000000 MOV DWORD PTR SS:[EBP-0x34],0x0
 *  0046960B   C745 D0 0F000000 MOV DWORD PTR SS:[EBP-0x30],0xF
 *  00469612   C645 BC 00       MOV BYTE PTR SS:[EBP-0x44],0x0
 *  00469616   8B4D F4          MOV ECX,DWORD PTR SS:[EBP-0xC]
 *  00469619   64:890D 00000000 MOV DWORD PTR FS:[0],ECX
 *  00469620   59               POP ECX
 *  00469621   5F               POP EDI
 *  00469622   5E               POP ESI
 *  00469623   5B               POP EBX
 *  00469624   8B4D F0          MOV ECX,DWORD PTR SS:[EBP-0x10]
 *  00469627   33CD             XOR ECX,EBP
 *  00469629   E8 209D1800      CALL .005F334E
 *  0046962E   8BE5             MOV ESP,EBP
 *  00469630   5D               POP EBP
 *  00469631   C2 1000          RETN 0x10
 *  00469634   CC               INT3
 *  00469635   CC               INT3
 *  00469636   CC               INT3
 *  00469637   CC               INT3
 *  00469638   CC               INT3
 *  00469639   CC               INT3
 *  0046963A   CC               INT3
 */
bool attach(ulong startAddress, ulong stopAddress, bool hijackGDI) // attach scenario
{
  ulong lastCaller = 0,
        lastCall = 0;
  auto fun = [&lastCaller, &lastCall](ulong caller, ulong call) -> bool {
    lastCaller = caller;
    lastCall = call;
    return true; // find last caller && call
  };
  MemDbg::iterCallerAddressAfterInt3(fun, (ulong)::GetTextExtentPoint32A, startAddress, stopAddress);
  if (!lastCaller)
    return false;

  // Check caller that is not after int3 for old AGE game 神採りアルケミーマイスター
  // 0045AB1D   C2 1000          RETN 0x10
  // 0045AB20   55               PUSH EBP
  {
    enum : DWORD { sig = 0x550010c2 };
    enum { fun_offset = 3 };
    for (auto addr = lastCaller; addr < lastCall; addr++)
      if (*(DWORD *)addr == sig) {
        lastCaller = addr + fun_offset;
        DOUT("scenario signature matches old age engine");
        break;
      }
  }

  if (!winhook::hook_before(lastCaller, Private::hookBefore))
    return false;
  if (hijackGDI)
    winhook::replace_near_call(lastCall, (ulong)Hijack::newGetTextExtentPoint32A);
  return true;
}

} // namespace ScenarioHook

namespace OtherHook {
namespace Private {
  /**
   *  Find the caller of two GetGlyphOutlineA in the middle.
   *  Sample game: 神のラプソディ
   *
   *  0046E173   FF15 2C406100    CALL DWORD PTR DS:[0x61402C]             ; gdi32.GetGlyphOutlineA
   *  0046E1F8   FF15 2C406100    CALL DWORD PTR DS:[0x61402C]             ; gdi32.GetGlyphOutlineA
   *
   *  The two GetGlyphOutlineA are in the same function that are at the end of all GetGlyphOutlineA
   *
   *  0046DBCE   CC               INT3
   *  0046DBCF   CC               INT3
   *  0046DBD0   55               PUSH EBP
   *  0046DBD1   8BEC             MOV EBP,ESP
   *  0046DBD3   81EC 98000000    SUB ESP,0x98
   *  0046DBD9   A1 80D36600      MOV EAX,DWORD PTR DS:[0x66D380]
   *  0046DBDE   33C5             XOR EAX,EBP
   *  0046DBE0   8945 FC          MOV DWORD PTR SS:[EBP-0x4],EAX
   *  0046DBE3   53               PUSH EBX
   *  0046DBE4   56               PUSH ESI
   *  0046DBE5   8B75 1C          MOV ESI,DWORD PTR SS:[EBP+0x1C]
   *  0046DBE8   8BD9             MOV EBX,ECX
   *  0046DBEA   8B83 0C040000    MOV EAX,DWORD PTR DS:[EBX+0x40C]
   *  0046DBF0   57               PUSH EDI
   *  0046DBF1   33FF             XOR EDI,EDI
   *  0046DBF3   33D2             XOR EDX,EDX
   *  0046DBF5   33C9             XOR ECX,ECX
   *
   *  Regsiters:
   *  EAX 00000002
   *  ECX 01F54C9C
   *  EDX 00000002
   *  EBX 028BDD10  ; jichi: text is here in ebx
   *  ESP 0012F240
   *  EBP 0012F2A8
   *  ESI 01F54C9C
   *  EDI 00000092
   *  EIP 0046DBD0 .0046DBD0
   *
   *  Runtime stack:
   *  0012F240   00454A3A  RETURN to .00454A3A from .0046DBD0
   *  0012F244   00000092
   *  0012F248   00000002
   *  0012F24C   00000002
   *  0012F250   FFFFFFF5
   *  0012F254   00000013
   *  0012F258   028BDD10   ; jichi: text is here
   *  0012F25C   00000001
   *  0012F260   00000000
   *  0012F264   01F40020
   *  0012F268   00000000
   *  0012F26C   00000016
   *  0012F270   00000013
   */
  bool hookBefore(winhook::hook_stack *s)
  {
    static QByteArray data_; // persistent storage, which makes this function not thread-safe

    // All threads including character names are linked together
    enum { role = Engine::OtherRole, sig = 0 };

    LPCSTR text = (LPCSTR)s->stack[6]; // arg6
    if (!text || ::strlen(text) <= 2) // skip single character
      return true;

    data_ = EngineController::instance()->dispatchTextA(text, role, sig);
    s->stack[6] = (ulong)data_.constData(); // arg2
    return true;
  }

} // namespace Private

bool attach(ulong startAddress, ulong stopAddress, bool hijackGDI) // attach scenario
{
  ulong thisCaller = 0,
        thisCall = 0,
        prevCall = 0;
  auto fun = [&thisCaller, &thisCall, &prevCall](ulong caller, ulong call) -> bool {
    if (call - prevCall == 133) { // 0x0046e1f8 - 0x0046e173 = 133
      thisCaller = caller;
      thisCall = call;
      return false; // stop iteration
    }
    prevCall = call;
    return true; // continue iteration
  };
  MemDbg::iterCallerAddressAfterInt3(fun, (ulong)::GetGlyphOutlineA, startAddress, stopAddress);
  if (!thisCaller || !winhook::hook_before(thisCaller, Private::hookBefore))
    return false;
  if (hijackGDI) {
    winhook::replace_near_call(thisCall, (ulong)Hijack::newGetGlyphOutlineA);
    winhook::replace_near_call(prevCall, (ulong)Hijack::newGetGlyphOutlineA);
  }
  return true;
}
} // namespace OtherHook

namespace Patch
{

/**
 *  Disable annoying message box popups
 *  Sample game: 神のラプソディ
 *  Example popup images: http://capita.tistory.com/108
 *
 *  My logic:
 *  1. Find the address of the first sjis message.
 *  2. Find the address when it is used as parameter of push
 *  3. Find the second call after the push
 *  4. Find the function being called
 *  5. Hijack the called function with a dummy msgbox
 *
 *  Sample code region for messages:
 *
 *  - Search: データが壊れています
 *    SJIS: 8366815b835e82aa89f382ea82c482a282dc82b7
 *  Found two matches.
 *  The second match is right, which is after zeros
 *  006162F8  54 2E 42 49 4E 00 00 00 00 00 00 00 00 00 00 00  T.BIN...........
 *  00616308  83 66 81 5B 83 5E 82 AA 89 F3 82 EA 82 C4 82 A2  データが壊れてい
 *  00616318  82 DC 82 B7 81 44 0A 8D C4 83 43 83 93 83 58 83  ます．.再インス・
 *  00616328  67 81 5B 83 8B 82 B5 82 C4 82 AD 82 BE 82 B3 82  gールしてくださ・
 *  00616338  A2 81 44 0A 0A 00 00 00 45 78 69 74 0D 0A 00 00  ｢．.....Exit....
 *
 *  0061840B  5B 28 32 2D 31 29 0D 0A 00 8A D6 90 94 81 46 4C  [(2-1)...関数：L
 *  0061841B  6F 61 64 44 61 74 61 20 83 47 83 89 81 5B 81 46  oadData エラー：
 *  0061842B  83 66 81 5B 83 5E 82 AA 89 F3 82 EA 82 C4 82 A2  データが壊れてい
 *  0061843B  82 DC 82 B7 81 44 0D 0A 00 8A D6 90 94 81 46 4C  ます．...関数：L
 *  0061844B  6F 61 64 44 61 74 61 20 83 47 83 89 81 5B 81 46  oadData エラー：
 *  0061845B  43 52 43 83 47 83 89 81 5B 28 31 2D 32 29 0D 0A  CRCエラー(1-2)..
 *  0061846B  00 8A D6 90 94 81 46 4C 6F 61 64 44 61 74 61 20  .関数：LoadData
 *  0061847B  83 47 83 89 81 5B 81 46 43 52 43 83 47 83 89 81  エラー：CRCエラ・
 *  0061848B  5B 28 31 2D 31 29 0D 0A 00 00 00 00 00 8A D6 90  [(1-1).......関・
 *  0061849B  94 81 46 4C 6F 61 64 44 61 74 61 20 83 47 83 89  煤FLoadData エラ
 *
 *  - Search: プログラムを続行しますか？
 *    SJIS: 8376838d834f8389838082f091b18d7382b582dc82b782a98148
 *  0061599E  83 76 83 8D 83 4F 83 89 83 80 82 F0 91 B1 8D 73  プログラムを続行
 *  006159AE  82 B5 82 DC 82 B7 82 A9 81 48 0A 0A 92 86 8E 7E  しますか？..中止
 *  006159BE  81 46 83 76 83 8D 83 4F 83 89 83 80 82 F0 8F 49  ：プログラムを終
 *  006159CE  97 B9 82 B5 82 DC 82 B7 81 44 0A 8D C4 8E 8E 8D  了します．.再試・
 *  006159DE  73 81 46 82 E0 82 A4 88 EA 93 78 82 B1 82 CC 83  s：もう一度この・
 *  006159EE  52 83 7D 83 93 83 68 82 F0 8E C0 8D 73 82 B5 82  Rマンドを実行し・
 *  006159FE  DC 82 B7 81 44 0A 20 20 20 20 20 20 20 20 28 82  ﾜす．.        (・
 *
 *  00411DA9   8D7E 08          LEA EDI,DWORD PTR DS:[ESI+0x8]
 *  00411DAC   68 08636100      PUSH .00616308  ; jichi: msg pushed here
 *  00411DB1   68 00040000      PUSH 0x400
 *  00411DB6   57               PUSH EDI
 *  00411DB7   E8 945EFFFF      CALL .00407C50
 *  00411DBC   83C4 0C          ADD ESP,0xC
 *  00411DBF   6A 05            PUSH 0x5
 *  00411DC1   57               PUSH EDI
 *  00411DC2   8B96 64EA0500    MOV EDX,DWORD PTR DS:[ESI+0x5EA64]
 *  00411DC8   52               PUSH EDX
 *  00411DC9   8BCE             MOV ECX,ESI
 *  00411DCB   E8 2017FFFF      CALL .004034F0  ; jichi: popup done here
 *  00411DD0   8985 A4F8FFFF    MOV DWORD PTR SS:[EBP-0x75C],EAX
 *  00411DD6   83F8 01          CMP EAX,0x1
 *  00411DD9   75 1F            JNZ SHORT .00411DFA
 *  00411DDB   33C0             XOR EAX,EAX
 *  00411DDD   8985 F8F7FFFF    MOV DWORD PTR SS:[EBP-0x808],EAX
 *  00411DE3   8985 7CF8FFFF    MOV DWORD PTR SS:[EBP-0x784],EAX
 */
namespace Private {

  // My own msgbox function to hook
  int msgbox(const char *text, const char *caption, uint type)
  {
    Q_UNUSED(text);
    Q_UNUSED(caption);
    if (type == MB_RETRYCANCEL)
      return IDRETRY;
    return 0;
  }

} // namespace Private

bool removePopups(ulong startAddress, ulong stopAddress)
{
  // hexstr: データが壊れています．
  // Prepend 00 at the beginning
  const char *msg = "\x00\x83\x66\x81\x5b\x83\x5e\x82\xaa\x89\xf3\x82\xea\x82\xc4\x82\xa2\x82\xdc\x82\xb7\x81\x44";
  ulong addr = MemDbg::findBytes(msg, 1 + ::strlen(msg+1), startAddress, stopAddress);
  if (!addr)
    return false;
  addr++; // skip the leading zero

  addr = MemDbg::findPushAddress(addr, startAddress, stopAddress);
  if (!addr)
    return false;

  ulong limit = addr + 100;  // 0x00411DCB - 0x00411DAC = 31
  addr = Engine::findNearCall(addr, limit);
  if (!addr)
    return false;
  addr += ::disasm((LPCVOID)addr); // skip the current call instruction
  addr = Engine::findNearCall(addr, limit); // find second call
  if (!addr)
    return false;

  addr = winasm::get_jmp_absaddr(addr);
  return winhook::replace_fun(addr, (ulong)Private::msgbox);
}

} // namespace Patch

} // unnamed namespace

/** Public class */

bool ARCGameEngine::attach()
{
  ulong startAddress, stopAddress;
  if (!Engine::getProcessMemoryRange(&startAddress, &stopAddress))
    return false;
  enum { DynamicEncoding = true };
  if (!ScenarioHook::attach(startAddress, stopAddress, DynamicEncoding))
    return false;
  if (OtherHook::attach(startAddress, stopAddress, DynamicEncoding))
    DOUT("other text found");
  else
    DOUT("other text NOT FOUND");
  if (Patch::removePopups(startAddress, stopAddress))
    DOUT("remove popups succeed");
  else
    DOUT("remove popups FAILED");
  HijackManager::instance()->attachFunction((ulong)::CreateFontIndirectA);
  return true;
}

QString ARCGameEngine::textFilter(const QString &text, int role)
{
  Q_UNUSED(role);
  QString ret = text;
  ret = ret.replace(L'\ufffd', L'\u2015');
  return ret;
}

// EOF

#if 0

/**
 *  Sample game: 姫狩りダンジョンマイスター体験版
 *
 *  Caller of the last GetTextExtentPoint32A: 0x451170
 *  0045116e   cc               int3
 *  0045116f   cc               int3
 *  00451170   6a ff            push -0x1 ; jichi: function starts
 *  00451172   68 c0e25500      push age.0055e2c0
 *  00451177   64:a1 00000000   mov eax,dword ptr fs:[0]
 *  0045117d   50               push eax
 *  0045117e   81ec a4000000    sub esp,0xa4
 *  00451184   a1 80485b00      mov eax,dword ptr ds:[0x5b4880]
 *  00451189   33c4             xor eax,esp
 *  0045118b   898424 a0000000  mov dword ptr ss:[esp+0xa0],eax
 *  00451192   53               push ebx
 *  00451193   55               push ebp
 *  00451194   56               push esi
 *  00451195   57               push edi
 *  00451196   a1 80485b00      mov eax,dword ptr ds:[0x5b4880]
 *  0045119b   33c4             xor eax,esp
 *  0045119d   50               push eax
 *  0045119e   8d8424 b8000000  lea eax,dword ptr ss:[esp+0xb8]
 *  004511a5   64:a3 00000000   mov dword ptr fs:[0],eax
 *  004511ab   8bbc24 cc000000  mov edi,dword ptr ss:[esp+0xcc]
 *  004511b2   8b8424 d0000000  mov eax,dword ptr ss:[esp+0xd0]
 *  004511b9   8bf1             mov esi,ecx
 *  004511bb   897c24 24        mov dword ptr ss:[esp+0x24],edi
 *  004511bf   894424 44        mov dword ptr ss:[esp+0x44],eax
 *  004511c3   c78424 b0000000 >mov dword ptr ss:[esp+0xb0],0xf
 *  004511ce   c78424 ac000000 >mov dword ptr ss:[esp+0xac],0x0
 *  004511d9   c68424 9c000000 >mov byte ptr ss:[esp+0x9c],0x0
 *  004511e1   ba 01000000      mov edx,0x1
 *  004511e6   899424 c0000000  mov dword ptr ss:[esp+0xc0],edx
 *  004511ed   803f 00          cmp byte ptr ds:[edi],0x0
 *  004511f0   75 1b            jnz short age.0045120d
 *  004511f2   c78424 c0000000 >mov dword ptr ss:[esp+0xc0],-0x1
 *  004511fd   8d4c24 6c        lea ecx,dword ptr ss:[esp+0x6c]
 *  00451201   e8 baacffff      call age.0044bec0
 *  00451206   33c0             xor eax,eax
 *  00451208   e9 38060000      jmp age.00451845
 *  0045120d   8b9c24 c8000000  mov ebx,dword ptr ss:[esp+0xc8]
 *  00451214   85db             test ebx,ebx
 *  00451216   75 06            jnz short age.0045121e
 *  00451218   8b9e c8040000    mov ebx,dword ptr ds:[esi+0x4c8]
 *  0045121e   8b8c9e 14040000  mov ecx,dword ptr ds:[esi+ebx*4+0x414]
 *  00451225   c64424 16 00     mov byte ptr ss:[esp+0x16],0x0
 *  0045122a   3951 70          cmp dword ptr ds:[ecx+0x70],edx
 *  0045122d   897c24 18        mov dword ptr ss:[esp+0x18],edi
 *  00451231   894424 20        mov dword ptr ss:[esp+0x20],eax
 *  00451235   897c24 1c        mov dword ptr ss:[esp+0x1c],edi
 *  00451239   75 2f            jnz short age.0045126a
 *  0045123b   8b8c24 d4000000  mov ecx,dword ptr ss:[esp+0xd4]
 *  00451242   51               push ecx
 *  00451243   50               push eax
 *  00451244   57               push edi
 *  00451245   53               push ebx
 *  00451246   8bce             mov ecx,esi
 *  00451248   e8 c3f8ffff      call age.00450b10
 *  0045124d   8bf0             mov esi,eax
 *  0045124f   c78424 c0000000 >mov dword ptr ss:[esp+0xc0],-0x1
 *  0045125a   8d4c24 6c        lea ecx,dword ptr ss:[esp+0x6c]
 *  0045125e   e8 5dacffff      call age.0044bec0
 *  00451263   8bc6             mov eax,esi
 *  00451265   e9 db050000      jmp age.00451845
 *  0045126a   8b41 30          mov eax,dword ptr ds:[ecx+0x30]
 *  0045126d   85c0             test eax,eax
 *  0045126f   74 16            je short age.00451287
 *  00451271   8b51 34          mov edx,dword ptr ds:[ecx+0x34]
 *  00451274   2bd0             sub edx,eax
 *  00451276   b8 67666666      mov eax,0x66666667
 *  0045127b   f7ea             imul edx
 *  0045127d   c1fa 03          sar edx,0x3
 *  00451280   8bc2             mov eax,edx
 *  00451282   c1e8 1f          shr eax,0x1f
 *  00451285   03c2             add eax,edx
 *  00451287   83c0 ff          add eax,-0x1
 *  0045128a   50               push eax
 *  0045128b   894424 2c        mov dword ptr ss:[esp+0x2c],eax
 *  0045128f   e8 7c90ffff      call age.0044a310
 *  00451294   8b10             mov edx,dword ptr ds:[eax]
 *  00451296   8b40 04          mov eax,dword ptr ds:[eax+0x4]
 *  00451299   894424 34        mov dword ptr ss:[esp+0x34],eax
 *  0045129d   8b849e 14040000  mov eax,dword ptr ds:[esi+ebx*4+0x414]
 *  004512a4   8b48 30          mov ecx,dword ptr ds:[eax+0x30]
 *  004512a7   83c0 2c          add eax,0x2c
 *  004512aa   85c9             test ecx,ecx
 *  004512ac   895424 30        mov dword ptr ss:[esp+0x30],edx
 *  004512b0   75 04            jnz short age.004512b6
 *  004512b2   33c0             xor eax,eax
 *  004512b4   eb 16            jmp short age.004512cc
 *  004512b6   8b50 08          mov edx,dword ptr ds:[eax+0x8]
 *  004512b9   2bd1             sub edx,ecx
 *  004512bb   b8 67666666      mov eax,0x66666667
 *  004512c0   f7ea             imul edx
 *  004512c2   c1fa 03          sar edx,0x3
 *  004512c5   8bc2             mov eax,edx
 *  004512c7   c1e8 1f          shr eax,0x1f
 *  004512ca   03c2             add eax,edx
 *  004512cc   83c0 ff          add eax,-0x1
 *  004512cf   8986 70050000    mov dword ptr ds:[esi+0x570],eax
 *  004512d5   803f 00          cmp byte ptr ds:[edi],0x0
 *  004512d8   0f84 10040000    je age.004516ee
 *  004512de   8bbc9e 14040000  mov edi,dword ptr ds:[esi+ebx*4+0x414]
 *  004512e5   8b6f 34          mov ebp,dword ptr ds:[edi+0x34]
 *  004512e8   83c7 2c          add edi,0x2c
 *  004512eb   396f 04          cmp dword ptr ds:[edi+0x4],ebp
 *  004512ee   76 05            jbe short age.004512f5
 *  004512f0   e8 9a190f00      call age.00542c8f
 *  004512f5   8d45 ec          lea eax,dword ptr ss:[ebp-0x14]
 *  004512f8   3b47 08          cmp eax,dword ptr ds:[edi+0x8]
 *  004512fb   896c24 54        mov dword ptr ss:[esp+0x54],ebp
 *  004512ff   77 05            ja short age.00451306
 *  00451301   3b47 04          cmp eax,dword ptr ds:[edi+0x4]
 *  00451304   73 05            jnb short age.0045130b
 *  00451306   e8 84190f00      call age.00542c8f
 *  0045130b   83c5 ec          add ebp,-0x14
 *  0045130e   3b6f 08          cmp ebp,dword ptr ds:[edi+0x8]
 *  00451311   72 05            jb short age.00451318
 *  00451313   e8 77190f00      call age.00542c8f
 *  00451318   8d7d 04          lea edi,dword ptr ss:[ebp+0x4]
 *  0045131b   8b6c24 18        mov ebp,dword ptr ss:[esp+0x18]
 *  0045131f   8a45 00          mov al,byte ptr ss:[ebp]
 *  00451322   3c 20            cmp al,0x20
 *  00451324   72 04            jb short age.0045132a
 *  00451326   3c 7f            cmp al,0x7f
 *  00451328   72 35            jb short age.0045135f
 *  0045132a   8ac8             mov cl,al
 *  0045132c   80c1 60          add cl,0x60
 *  0045132f   80f9 3f          cmp cl,0x3f
 *  00451332   76 2b            jbe short age.0045135f
 *  00451334   3c 80            cmp al,0x80
 *  00451336   72 27            jb short age.0045135f
 *  00451338   66:8b55 00       mov dx,word ptr ss:[ebp]
 *  0045133c   66:895424 14     mov word ptr ss:[esp+0x14],dx
 *  00451341   8a4424 14        mov al,byte ptr ss:[esp+0x14]
 *  00451345   3c 20            cmp al,0x20
 *  00451347   72 04            jb short age.0045134d
 *  00451349   3c 7f            cmp al,0x7f
 *  0045134b   72 16            jb short age.00451363
 *  0045134d   3c a0            cmp al,0xa0
 *  0045134f   72 04            jb short age.00451355
 *  00451351   3c e0            cmp al,0xe0
 *  00451353   72 0e            jb short age.00451363
 *  00451355   c74424 2c 020000>mov dword ptr ss:[esp+0x2c],0x2
 *  0045135d   eb 11            jmp short age.00451370
 *  0045135f   884424 14        mov byte ptr ss:[esp+0x14],al
 *  00451363   c64424 15 00     mov byte ptr ss:[esp+0x15],0x0
 *  00451368   c74424 2c 010000>mov dword ptr ss:[esp+0x2c],0x1
 *  00451370   8d4424 14        lea eax,dword ptr ss:[esp+0x14]
 *  00451374   8d50 01          lea edx,dword ptr ds:[eax+0x1]
 *  00451377   8a08             mov cl,byte ptr ds:[eax]
 *  00451379   83c0 01          add eax,0x1
 *  0045137c   84c9             test cl,cl
 *  0045137e  ^75 f7            jnz short age.00451377
 *  00451380   2bc2             sub eax,edx
 *  00451382   8d4c24 48        lea ecx,dword ptr ss:[esp+0x48]
 *  00451386   51               push ecx
 *  00451387   50               push eax
 *  00451388   8b86 50040000    mov eax,dword ptr ds:[esi+0x450]
 *  0045138e   8d5424 1c        lea edx,dword ptr ss:[esp+0x1c]
 *  00451392   52               push edx
 *  00451393   50               push eax
 *  00451394   ff15 34205600    call dword ptr ds:[0x562034]             ; gdi32.gettextextentpoint32a
 *  0045139a   8b4f 04          mov ecx,dword ptr ds:[edi+0x4]
 *  0045139d   034c24 4c        add ecx,dword ptr ss:[esp+0x4c]
 *  004513a1   8b17             mov edx,dword ptr ds:[edi]
 *  004513a3   035424 48        add edx,dword ptr ss:[esp+0x48]
 *  004513a7   51               push ecx
 *  004513a8   8b8c9e 14040000  mov ecx,dword ptr ds:[esi+ebx*4+0x414]
 *  004513af   52               push edx
 *  004513b0   e8 bb760000      call age.00458a70
 *  004513b5   a8 01            test al,0x1
 *  004513b7   0f84 28020000    je age.004515e5
 *  004513bd   83be 78050000 01 cmp dword ptr ds:[esi+0x578],0x1
 *  004513c4   0f85 23020000    jnz age.004515ed
 *  004513ca   0fb64424 14      movzx eax,byte ptr ss:[esp+0x14]
 *  004513cf   8a5424 15        mov dl,byte ptr ss:[esp+0x15]
 *  004513d3   8da8 7fffffff    lea ebp,dword ptr ds:[eax-0x81]
 *  004513d9   8bc5             mov eax,ebp
 *  004513db   85c0             test eax,eax
 *  004513dd   75 08            jnz short age.004513e7
 *  004513df   0fb6c2           movzx eax,dl
 *  004513e2   83e8 41          sub eax,0x41
 *  004513e5   74 0e            je short age.004513f5
 *  004513e7   85c0             test eax,eax
 *  004513e9   b9 01000000      mov ecx,0x1
 *  004513ee   7f 07            jg short age.004513f7
 *  004513f0   83c9 ff          or ecx,0xffffffff
 *  004513f3   eb 02            jmp short age.004513f7
 *  004513f5   33c9             xor ecx,ecx
 *  004513f7   85c9             test ecx,ecx
 *  004513f9   0f84 ee010000    je age.004515ed
 *  004513ff   8bc5             mov eax,ebp
 *  00451401   85c0             test eax,eax
 *  00451403   75 08            jnz short age.0045140d
 *  00451405   0fb6c2           movzx eax,dl
 *  00451408   83e8 42          sub eax,0x42
 *  0045140b   74 0e            je short age.0045141b
 *  0045140d   85c0             test eax,eax
 *  0045140f   b9 01000000      mov ecx,0x1
 *  00451414   7f 07            jg short age.0045141d
 *  00451416   83c9 ff          or ecx,0xffffffff
 *  00451419   eb 02            jmp short age.0045141d
 *  0045141b   33c9             xor ecx,ecx
 *  0045141d   85c9             test ecx,ecx
 *  0045141f   0f84 c8010000    je age.004515ed
 *  00451425   8bc5             mov eax,ebp
 *  00451427   85c0             test eax,eax
 *  00451429   75 08            jnz short age.00451433
 *  0045142b   0fb6c2           movzx eax,dl
 *  0045142e   83e8 76          sub eax,0x76
 *  00451431   74 0e            je short age.00451441
 *  00451433   85c0             test eax,eax
 *  00451435   b9 01000000      mov ecx,0x1
 *  0045143a   7f 07            jg short age.00451443
 *  0045143c   83c9 ff          or ecx,0xffffffff
 *  0045143f   eb 02            jmp short age.00451443
 *  00451441   33c9             xor ecx,ecx
 *  00451443   85c9             test ecx,ecx
 *  00451445   0f84 a2010000    je age.004515ed
 *  0045144b   8b7c24 18        mov edi,dword ptr ss:[esp+0x18]
 *  0045144f   2b7c24 1c        sub edi,dword ptr ss:[esp+0x1c]
 *  00451453   897c24 40        mov dword ptr ss:[esp+0x40],edi
 *  00451457   83c7 01          add edi,0x1
 *  0045145a   57               push edi
 *  0045145b   e8 4e0a0f00      call age.00541eae
 *  00451460   8b4c24 20        mov ecx,dword ptr ss:[esp+0x20]
 *  00451464   8be8             mov ebp,eax
 *
 *  Sample game: 天秤のLaDEA体験版
 *  at 0x468fa0
 *  Caller of the -3 GetTextExtentPoint32A: 0x46921f
 *  Caller of the -2 GetTextExtentPoint32A: 0x46965f
 *  Caller of the -1 GetTextExtentPoint32A: 0x4699b1
 *
 */
static ulong searchEushully(ulong startAddress, ulong stopAddress)
{
  //const BYTE bytes[] = { // size = 14
  //  0x01,0x53, 0x58,                // 0153 58          add dword ptr ds:[ebx+58],edx
  //  0x8b,0x95, 0x34,0xfd,0xff,0xff, // 8b95 34fdffff    mov edx,dword ptr ss:[ebp-2cc]
  //  0x8b,0x43, 0x58,                // 8b43 58          mov eax,dword ptr ds:[ebx+58]
  //  0x3b,0xd7                       // 3bd7             cmp edx,edi ; hook here
  //};
  //enum { cur_ins_size = 2 };
  //enum { hook_offset = sizeof(bytes) - cur_ins_size }; // = 14 - 2  = 12, current inst is the last one
  const uint8_t bytes1[] = {
    0x3b,0xd7, // 013baf32  |. 3bd7       |cmp edx,edi ; jichi: ITH hook here, char saved in edi
    0x75,0x4b  // 013baf34  |. 75 4b      |jnz short siglusen.013baf81
  };
  //enum { hook_offset = 0 };
  //DWORD range1 = qMin(stopAddress - startAddress, Engine::MaximumMemoryRange);
  ulong addr = MemDbg::findBytes(bytes1, sizeof(bytes1), startAddress, stopAddress);
  if (!addr)
    //ConsoleOutput("vnreng:Siglus2: pattern not found");
    return 0;

  const uint8_t bytes2[] = {
    0x55,      // 013bac70  /$ 55       push ebp ; jichi: function starts
    0x8b,0xec, // 013bac71  |. 8bec     mov ebp,esp
    0x6a,0xff  // 013bac73  |. 6a ff    push -0x1
  };
  enum { range = 0x300 }; // 0x013baf32  -0x013bac70 = 706 = 0x2c2
  return MemDbg::findBytes(bytes2, sizeof(bytes2), addr - range, addr); // search backward
  //if (!addr)
  //  //ConsoleOutput("vnreng:Siglus2: pattern not found");
  //  return 0;
  //return addr;
}

#endif // 0
