//   NM32 File data arrangement (NMS file from SIce)
//   NM32 File includes every wish you would have. :)
//        version: 0.11
//
//   NOTICE!
//   All names represented abridgements like NMDR, ... are my (that means, that they are my logical
//   representatives of Numega's ones).
//
//   This text and all attributes in it were tested only on ASM programs,
//   so for everything else it doesn't have to be this way.
//   Questions to: mostekaccess@mailcity.com
//
//   BEFORE you mail me:
//   Look into 'Borland_subSectionTypes.txt' for additional explanations.
//   If you don't find the answer, than check the net(normally newer versions of this text
//   will first appear on Tsehp 'Fravia's Page of Reverse Engineering'),
//   if even then your question won't be answered mail me.
//
//   Peace
//   Mostek
//

#ifndef _NM32_
#define _NM32_

//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//   NM32 file structure
//
//   -----------------------
//   |NM32 Header          |
//   -----------------------
//   |debug info           |
//   |...                  |
//   -----------------------
//   |NMDR                 |
//   -----------------------
//   |sourceCode (optional)|
//   -----------------------
//
//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   NM32 Header:
//
//   offset  data     name
//   0       ULONG    NM32(string)
//   4       ULONG    verMajor(10)
//   8       ULONG    verMinor(1)
//   C       ULONG    offNMDR
//   10      ULONG    creationTime
//   14      ULONG    creationNumber
//   18      ULONG    fileType
//   1C      ULONG    fileLength
//   20    8*ULONG    NULL
//   40      *        filePath (104h bytes)
//   144     *        copyrightString (100h bytes)
//   244              (End of NM32 Header)
//
struct NM32_HEADER
{
	unsigned long	NM32;
	unsigned long	verMajor;	//I think version MAJOR
	unsigned long	verMinor;	//        version MINOR
	unsigned long	offNMDR;
	unsigned long	creationTime;
	unsigned long	creationNumber;
	unsigned long	fileType;
	unsigned long	fileLength;
	unsigned long	N1;
	unsigned long	N2;
	unsigned long	N3;
	unsigned long	N4;
	unsigned long	N5;
	unsigned long	N6;
	unsigned long	N7;
	unsigned long	N8;
	char			filePath[0x104];	//MAX_PATH
	char			copyrightString[0x100];
};

#define	NM32s	0x32334D4E

//   verMajor - Major version of the NM32 file. This file is made for verMajor=10.
//   verMinor - Minor version of the NM32 file. This file is made for verMinor=1.
//   offNMDR - Offset in file to NM debug record.
//   creationTime - I think number of seconds until this second. (function: Time(NULL) )
//   ---------------------------------------------------------------------
//   creationNumber:
//             -translate:    1000 *Public Only Checked
//                            2000 *Type Information Only Checked
//                            4000 *Symbols only (Includes locals and structures) Checked
//                            8000-Default *Symbols and Source code Checked
//                           10000 *Include source in NMS file Checked
//
//             -load:    1 *Load Only Symbol Information Checked
//                       2 *Load Executable Checked (Load Only Symbol Information Unchecked)
//                       4 *Load Executable As Debug Process Checked (Disabled)
//
//             -ini:     000-Default *Ignore DLL Loads Checked (Diasbled)
//                       100 *Load Exports For DLLs Checked (Disabled)
//                       200 *Load Symbols For DLLs Checked (Disabled)
//
//             -button:  10 *Stop at WinMain Checked
//                       40 *Prompt For Missing Code UnChecked
//          
//             The number is made by ORing master and minor choises (one of every group
//             (execept in translate where you can select 'Include source in NMS...' button too)).
#define	CN_T_PUBLICONLY		0x001000
#define	CN_T_TYPEONLY		0x002000
#define	CN_T_SYMBOLSONLY	0x004000
#define	CN_T_SYMBOLS_SOURCE	0x008000
#define	CN_T_INCLUDESOURCE	0x010000
//
#define	CN_L_SYBOLSONLY		0x01
#define	CN_L_EXECUTABLE		0x02
//#define	CN_L_EXECUTABLED	0x04
//
#define	CN_I_IGNOREDLL		0x0000
//#define	CN_I_DLLEXPORTS		0x0100
//#define	CN_I_DLLSYMBOLS		0x0200
//
#define	CN_B_STOPATWINMAIN	0x010
#define	CN_B_PROMPTFORCODE	0x040


//   ---------------------------------------------------------------------
//   filetype - Type of file loaded(converted) file.
//              *2h-PE_EXE
//              *4h-PE_DLL
//              *6h-LE_VXD
//              *7h-NE			//this one is not tested yet
//              *Ah-NMS
//              *Bh-map->sym->nms
//              *Eh-LX
//              *
//              *There are others,but I don't think they would make any use in this text.
#define	FT_PEEXE	0x02
#define	FT_PEDLL	0x04
#define	FT_LEVXD	0x06
#define FT_NE		0x07
#define	FT_NMS		0x0A
#define	FT_MAP		0x0B
#define	FT_LX		0x0E

//   ---------------------------------------------------------------------
//   fileLength - Length of *.NMS file
//   filePath - Path to module(*.exe, *.dll, ...).
//
//   copyrightString - 'NM32 Symbol Format - (C) Copyright Numega Technologies, 1996-1997. All Rights Reserved'
//                     *(If *.NMS file will be created with IDA plugin ' IDA2NMS plugin version:x.xx' text will be added.)

//   ***********************************************************************************************************
//   ***********************************************************************************************************
//   NMDR (NM debug record)
//
//   NMDR_header:
//   offset  data     name
//   0       ULONG    NMDR(string)
//   4       ULONG    cNMDE
//   8       ULONG    offGTYP
//   C       ULONG    offSTTB
//   10      ULONG    offSYMD
//   14      ULONG    offSRCP
//   18      ULONG    offFPOD
//   1C    7*ULONG    NULL
//
//   cNMDE - count of NMDEs (NMDE - NM debug entry)
//   offGTYP - Offset in file to GTYP.
//   offSTTB - Offset in file to STTB.
//   offSYMD - Offset in file to SYMD.
//   offSRCP - Offset in file to SRCP.
//   offFPOD - Offset in file to FPOD.
struct	NMDR_HEADER
{
	unsigned long	NMDR;
	unsigned long	cNMDE;
	unsigned long	offGYTP;
	unsigned long	offSTTB;
	unsigned long	offSYMD;
	unsigned long	offSRCP;
	unsigned long	offFPOD;
	unsigned long	N1;
	unsigned long	N2;
	unsigned long	N3;
	unsigned long	N4;
	unsigned long	N5;
	unsigned long	N6;
	unsigned long	N7;
};
#define	NMDRs	0x52444D4E

//   ---------------------------------------------------------------------
//   NMDE (NM debug entry)
//   It's right after NMDR_header.
//
//   offset  data     name
//   0       ULONG    NMDE(string)
//   4       ULONG    entryIndex
//   8       ULONG    offEntry
//   C       ULONG    entryLength
//   10    5*ULONG    NULL
//
//   entryIndex - Type of entry.
//                *(Sequence of types are as they appear in NMDR.)
//                *NMTP - 3
//                *STTB - 2
//                *TYTB - 4
//                *HSHT - 5
//                *SYMD - 6
//                *FPOD - 8
//                *SRCP - 7
//                *GTYP - 1
//   offEntry - Offset in file to entry.
//   entryLength - Length of entry.
struct	NMDE_S
{
	unsigned long	NMDE;
	unsigned long	entryIndex;
	unsigned long	offEntry;
	unsigned long	entryLength;
	unsigned long	N1;
	unsigned long	N2;
	unsigned long	N3;
	unsigned long	N4;
	unsigned long	N5;
};
#define	NMDEs	0x45444D4E

#define INDEX_GTYP 1
#define INDEX_STTB 2
#define INDEX_NMTP 3
#define INDEX_TYTB 4
#define INDEX_HSHT 5
#define INDEX_SYMD 6
#define INDEX_SRCP 7
#define INDEX_FPOD 8

//   ---------------------------------------------------------------------
//   NRDS (NM record source)
//   (NMDR finishes with this string.)
//   After this text we can add source code files(one after another (without any byte between them)).
//
//   offset  data     name
//   0       ULONG    NRDS(string)
//   4       *        sourceCode (optional)
//
//   CAUTION!
//   File MUST finish on dword boundary.
#define	NRDSs	0x5344524E

//   ***********************************************************************************************************
//   ***********************************************************************************************************
//   ***********************************************************************************************************
//   NMTP (NM types)
//
//   -----------------------
//   |NMTP Header          |
//   -----------------------
//   |Offset to Types Data |
//   -----------------------
//   |Types Data           |
//   -----------------------
//
//   NMTP_header:
//   offset    data      name
//   0         ULONG     NMTP(string)
//   4         ULONG     sectionLength
//   8         ULONG     cTypes
//   C       2*ULONG     NULL
//
//   cTypes - Number of types defined in this section.
struct NMTP_HEADER
{
	unsigned long	NMTP;
	unsigned long	sectionLength;
	unsigned long	cTypes;
	unsigned long	N1;
	unsigned long	N2;
};
#define NMTPs 0x50544D4E 


//   ---------------------------------------------------------------------
//   Offset to Types Data:
//   offset      data      name
//   0    cTypes*ULONG     offType
//
//   offType - Are offsets from begining of the 'Types Data' subsection.
//             (So the first offType is NULL.)

//   ---------------------------------------------------------------------
//   Types Data:
//   TypeData section is a series of consecutive types structures.
//   First type has type index of 1000h, next 1001h, ....
//   Indexes are counted in NMS file and are NOT the same as in original file debug section.
//
//   offset    data      name
//   0         ULONG     type1Number (index:1000h)
//   4         *         type1Data
//   *         ULONG     type2Number (index:1001h)
//   *         ULONG     type2Data
//   ...
//
//   typeNumber - Type leaf number. Look into 'Type Strings Explained.txt' .
//
//
//   Types currently defined:
//   name                  SIce type string number
//   LF_ARRAY            = 1003h
//   LF_STRUCT(5h)       = 1005h
//   TYPE_LF_UNION       = 1006h
//   LF_PROCEDURE(8h)    = 8h
//   LF_LABEL(Eh)        = Eh
//
//   LF_ARGLIST(201h)    = 2201h
//   TYPE_LF_DERIVED     = 2204h
//
//   LF_MEMBER(406h)     = 1406h
#define TYPE_LF_ARRAY		0x1003		//type SoftIce LF_ARRAY
#define TYPE_LF_STRUCT		0x1005
#define TYPE_LF_UNION		0x1006
#define TYPE_LF_PROCEDURE	0x8
#define TYPE_LF_LABEL		0xE

#define TYPE_LF_ARGLIST		0x2201
#define TYPE_LF_DERIVED		0x2204

#define TYPE_LF_MEMBER		0x1406


//   ------------------------------------------------
//   Array:
//   offset    data      name
//   0         ULONG     1003h ("LF_ARRAY"=3h)
//   4         ULONG     elemType		//for strings T_UCHAR
//   8         ULONG     NULL
//   C         SHORT     NULL
//   E         ULONG     length
//   12        ULONG     indexType		//normal T_ULONG
//   16        ULONG     NULL
//   1A        ULONG     length
//   1E        SHORT     NULL
//
//   elemType - Type index of each array element (look into 'Primitive Type Listing.txt').
//   length - Length of array in bytes.
//   indexType - Type index of indexing variable (look into 'Primitive Type Listing.txt').
//
//   Notice!
//   One of the length variables is the length of the whole array and one is length of grouped elements in array.
//   But for a string there is no diference.
//   This will be fixed in one of the next versions.
struct DATAS_LF_ARRAY
{
	unsigned long	lf_index;
	unsigned long	elemType;
	unsigned long	N1;
	unsigned short	N2;
	unsigned long	length;
	unsigned long	indexType;
	unsigned long	N3;
	unsigned long	length2;
	unsigned short	N4;
};


//   ------------------------------------------------
//   Struct:
//   For member definition use LF_DERIVED.
//
//   offset    data      name
//   0         ULONG     1005h ("LF_STRUCT"=5h)
//   4         ULONG     derivedType
//   8         ULONG     iName
//   C         SHORT     property+reserved byte
//   E         ULONG     cFields
//   12        ULONG     length
//   16        ULONG     NULL
//   1A        ULONG     NULL
//   1E        SHORT     NULL
//
//   derivedType - Type record that specifies all of the classes that are directly derived
//                 from the class that references this type record.
//                 (used for struct members too)
//   iName - Index name in STTB.
//   ----------------------
//   property - Property bit field. (+ reserved byte)
//   Boolean: 0(No)/1(Yes)
//
//   offset(bit)    size   name
//   0(1.bit)       1bit   packed
//   1(2.bit)       1bit   ctor
//   2(3.bit)       1bit   overops
//   3(4.bit)       1bit   isnested
//   4(5.bit)       1bit   cnested
//   5(6.bit)       1bit   opassign
//   6(7.bit)       1bit   opcast
//   7(8.bit)       1bit   fwref
//
//   packed - Structure is packed.
//   ctor - Class has constructors and/or destructors.
//   overops - Class has overloaded operators.
//   isnested - Class is a nested class.
//   cnested - Class contains nested classes.
//   opassign - Class has overloaded assignment.
//   opcast - Class has casting methods.
//   fwdref - Class/structure is a forward (incomplete) reference.
//   ----------------------
//   cFields - Number of elements in the structure.
//   length - length of structure.
struct DATAS_LF_STRUCT
{
	unsigned long	lf_index;
	unsigned long	derivedType;
	unsigned long	iName;
	unsigned short	property;
	unsigned long	cFields;
	unsigned long	length;
	unsigned long	N1;
	unsigned long	N2;
	unsigned short	N3;
};
#define PRO_NULL		0x00
#define PRO_PACKED		0x01
#define PRO_CTOR		0x02
#define PRO_OVEROPS		0x04
#define PRO_ISNESTED	0x08
#define PRO_CNESTED		0x10
#define PRO_OPASSIGN	0x20
#define PRO_OPCAST		0x40
#define PRO_FWREF		0x80

//   ------------------------------------------------
//   Union:
//   Same as LF_STRUCT except that all members have offset 0.

//   ------------------------------------------------
//   Procedure:
//   offset    data      name
//   0         ULONG     8h (LF_PROCEDURE)
//   4         ULONG     argList
//   8         ULONG     rType
//   C         ULONG     call
//   10        ULONG     argCount
//
//
//   argList - Type index of argument list type record.
//   rType -  Type index of the value returned by the procedure.
//            (Look into 'Primitive Type Listing.txt'.)
//   ----------------------
//   call - Calling convention of the procedure.
//   0    Near C (arguments pushed right to left, caller pops arguments)
//   1    Far C
//   2    Near pascal  (arguments pushed left to right, callee pops arguments)
//   3    Far pascal
//   4    Near fastcall
//   5    Far fastcall
//   6    PCode
//   7    Near stdcall
//   8    Far stdcall
//   9    Near syscall
//   10   Far syscall
//   11   This call
//   12   MIPS call
//   13   Generic
//   14-255    Reserved
//   Borland supports from 0 to 10 (with 10).
//   Borland:- if bit 40h is set => Variable args (don't ask me what this means)
//           - if bit 80h is set => Fast This
//   ----------------------
//   argCount - Number of arguments passed to procedure.
struct DATAS_LF_PROCEDURE
{
	unsigned long	lf_index;
	unsigned long	argList;
	unsigned long	rType;
	unsigned long	call;
	unsigned long	argCount;
};

enum calling
{
	CALL_NEAR_C,
	CALL_FAR_C,
	CALL_NEAR_PASCAL,
	CALL_FAR_PASCAL,
	CALL_NEAR_FASTCALL,
	CALL_FAR_FASTCALL,
	CALL_PCODE,
	CALL_NEAR_STDCALL,
	CALL_FAR_STDCALL,
	CALL_NEAR_SYSCALL,
	CALL_FAR_SYSCALL,
	CALL_THIS,
	CALL_MIPS,
	CALL_GENERIC,
};

//   ------------------------------------------------
//   Label:
//   offset    data      name
//   0         ULONG     Eh (LF_LABEL)
//   4         ULONG     mode
//
//   mode - Addressing mode of the label
//          (0 NEAR label)
//          (4 FAR label)
//
//   Normaly NEAR and FAR label types are the first ones in NMTP.
struct DATAS_LF_LABEL
{
	unsigned long	lf_index;
	unsigned long	mode;
};
#define LABEL_NEAR	0x0
#define LABEL_FAR	0X4


//   ------------------------------------------------
//   Arglist:
//   offset       data      name
//   0            ULONG     2201h ("LF_ARGLIST"=201h)
//   4            ULONG     NULL
//   8            ULONG     argCount
//   C   argCount*ULONG     varType
//
//
//   argCount - Count of number of indices in list.
//   varType - Type index of each array element (look into 'Primitive Type Listing.txt').
//struct DATAS_LF_ARGLIST
//{
//	unsigned long	lf_index;
//	unsigned long	N1;
//	unsigned long	argCount;
//};


//   ------------------------------------------------
//   Derived Classes(in nms file used for structure members too):
//   This type record specifies all of the classes that are directly derived
//   from the class that references this type record.
//
//   offset       data      name
//   0            ULONG     2204h ("LF_DERIVED"=204h)
//   4            ULONG     NULL
//   8            ULONG     memCount
//   C      cType*ULONG     memType
//
//   memCount - Number of types in the list.
//   memType - Type indices of the classes that directly inherit from the class that references this type record.
//          (in nms file: member types)
//struct DATAS_LF_DERIVED
//{
//	unsigned long	lf_index;
//	unsigned long	N1;
//	unsigned long	cType;
//	unsigned long	memType;
//};


//   ------------------------------------------------
//   Member:
//   This leaf specifies nonstatic data members of a structure/class.
//   It must be defined in front of structure.
//
//   offset    data      name
//   0         ULONG     1406h ("LF_MEMBER"=406h)
//   4         ULONG     indexType
//   8         ULONG     iName
//   C         SHORT     access
//   E         SHORT     offset
//   10        ULONG     NULL //probably browserOffset
//
//   indexType - Type index of "LF_MEMBER" in "LF_FIELDLIST" (look into 'Primitive Type Listing.txt').
//               If member is an array of bytes than you must set an array type.
//   iName - Index name of indexType in STTB.
//   ----------------------------------------
//   access - ?(Normally none.(TASM))
//   0 none
//   1 private
//   2 protected
//   3 public
//   ----------------------------------------
//   offset - Offset of member(variable) in struct.
//   browserOffset - ?
struct DATAS_LF_MEMBER
{
	unsigned long	lf_index;
	unsigned long	indexType;
	unsigned long	iName;
	unsigned short	access;
	unsigned short	offset;
	unsigned long	N1;
}; 
#define ACCESS_NONE 0
#define ACCESS_PRIVATE 1
#define ACCESS_PROTECTED 2
#define ACCESS_PUBLIC 3


//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   STTB (String table)
//
//   ------------------------
//   |STTB Header           |
//   ------------------------
//   |Offsets               |
//   ------------------------
//   |String (Names Section)|
//   ------------------------
//
//
//   STTB_header
//   offset     data     name
//   0          ULONG    STTB(string)
//   4          ULONG    sectionLength
//   8          ULONG    cNames (+ 1)
//   C        2*ULONG    NULL
//
//   sectionLength - Length of STTB section.
//   cNames - Number of names(string).
//            * (+1)=>it's because zero string(just one zero byte) at the begining
struct STTB_HEADER
{
	unsigned long	STTB;
	unsigned long	sectionLength;
	unsigned long	cNames;
	unsigned long	N1;
	unsigned long	N2;
};
#define STTBs		0x42545453

//   ---------------------------------------------------------------------
//   Offsets to strings:
//   14         ULONG    NULL     |
//   18  cNames*ULONG    offNames | =>offsets to names (NULL at the begining is for iName=NULL)
//
//   offNames - Offsets of names in namesSubSection(first name starts with offset of 1h).
//   *          BYTE     0h				;zero ended string '\x0'
//   *          *        namesSection	;"1st" string
//
//   namesSection - All names with zero ended. (This section ends with so many zeros that next section
//                                              starts on DWORD boundary.)
//
//
//
//

											  
//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   TYTB (Type table)
//   This section defines typeDefs, structs and global procedures.
//   Same types are defined in HSHT too.
//
//   ------------------------
//   |TYTB Header           |
//   ------------------------
//   |Type Tables           |
//   ------------------------
//
//   TYTB_header:
//   offset    data      name
//   0         ULONG     TYTB(string)
//   4         ULONG     sectionLength
//   8         ULONG     cTypes
//   C         ULONG     offTypeTables
//   10      2*ULONG     NULL
//
//   cTypes - Number of types defined in this section.
//   offTypeTables - Offset from start of file to TYTB SubSection.
struct TYTB_HEADER
{
	unsigned long	TYTB;
	unsigned long	sectionLength;
	unsigned long	cTypes;
	unsigned long	offTypeTables;
	unsigned long	N1;
	unsigned long	N2;
};
#define TYTBs		0x42545954

//
//
//   TypeTable:
//   offset    data      name
//   0         ULONG     type
//   4         ULONG     iNameType
//
//   type - This is the type of typeDef(ex. ULONG) or struct or global procedure.
//   iNameType - Index name in STTB of typeDef or structure or global procedure.
struct	TYPETABLE
{
	unsigned long	type;
	unsigned long	iNameType;
};


//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   HSHT (Hash table)
//   This section defines typeDefs, structs and global procedures.
//   Same types are defined in TYTB too.
// 
//
//   HSHT_header:
//   offset    data      name
//   0         ULONG     HSHT(string)
//   4         ULONG     sectionLength
//   8         ULONG     sizeTableTOffsets
//   C         ULONG     cTypes
//   10        ULONG     offTableOffsets
//   14        ULONG     offTypeTables
//   18      2*DWORD     NULL
//
//   cTypes - Number of types included in this section.
//   sizeTableOffsets - Size of 'HSHT Type Table Offsets section' in DWORDs (25h normaly);
//   offTablesOffsets - Offset to "HSHT Type Table Offsets section" in file.
//   offTypeTables - Offset to "HSHT Type Tables section" in file.
struct HSHT_HEADER
{
	unsigned long	HSHT;
	unsigned long	sectionLength;
	unsigned long	sizeTableOffsets;
	unsigned long	cTypes;
	unsigned long	offTableOffsets;
	unsigned long	offTypeTables;
	unsigned long	N1;
	unsigned long	N2;
};
#define HSHTs		0x54485348

//   ---------------------------------------------------------------------
//   HSHT Type Table Offsets section:
//   offset    data      name
//   0         ULONG     x
//   4         ULONG     x
//   8         ULONG     x
//   C         ULONG     x
//   10        ULONG     x
//   14        ULONG     x
//   18        ULONG     x
//   1C        ULONG     x
//   20        ULONG     x
//   24        ULONG     x
//   28        ULONG     x
//   2C        ULONG     x
//   30        ULONG     x
//   34        ULONG     x
//   38        ULONG     x
//   3C        ULONG     x
//   40        ULONG     x
//   44        ULONG     x
//   48        ULONG     x
//   4C        ULONG     x
//   50        ULONG     x
//   54        ULONG     x
//   58        ULONG     x
//   5C        ULONG     x
//   60        ULONG     x
//   64        ULONG     x
//   68        ULONG     x
//   6C        ULONG     x
//   70        ULONG     x
//   74        ULONG     x
//   78        ULONG     x
//   7C        ULONG     x
//   80        ULONG     x
//   84        ULONG     x
//   88        ULONG     x
//   8C        ULONG     x
//   90        ULONG     x
//
//   x - (Offset to specificied HSHTTypeTable + 1) from begining of HSHT Type Tables..
//        *How to get variable offset:
//        *
//        *hashNumber/25h => remainder*4=offset in "HSHT Type Table Offset section"
//        *
//        *25h=size of HSHTTypeTablesOffsets section DWORDs.

//   ---------------------------------------------------------------------
//   HSHT Type Table section:
//
//   TypeTable:
//   offset    data      name
//   0         ULONG     offPreviousTable
//   4         ULONG     hashNumber
//   8         ULONG     iNameType
//   C         ULONG     type
//   10        ULONG     NULL
//
//   offPreviousTable - Offset from begining of "HSHT Type Tables section" + 1 to
//                      previous TypeTable that had same variable in "HSHT Type Table Offsets section".
//   ------------------------------------------------
//   hashNumber - It's created from string in STTB(iNameType).
//        *This is the code:
//        *
//        *    mov     esi, pToString_InSTTB
//        *    xor     edx, edx
//        *    mov     ecx, stringLength
//        *    shr     ecx, 2
//        *    jecxz   @LessThan4Letters
//        *@Loop1:
//        *    lodsd
//        *    and     eax, 0DFDFDFDFh       ;to big letters
//        *    xor     edx, eax
//        *    rol     edx, 4
//        *    loop    @Loop1
//        *
//        *@LessThan4Letters:
//        *    mov     ecx, stringLength
//        *    and     ecx, 3
//        *    jecxz   @NoLettersLeft
//        *    xor     eax, eax
//        *    add     esi, ecx
//        *    dec     esi
//        *    std
//        *
//        *@Loop2:
//        *    lodsb
//        *    and     al, 0DFh
//        *    shl     eax, 8
//        *    loop    @Loop2
//        *    cld
//        *    xor     edx, eax
//        *
//        *@NoLettersLeft:
//        *    mov     eax, edx
//   ------------------------------------------------
//   iNameType - Index name in STTB of typeDef or structure or global procedure.
//   type - This is the type of typeDef(ex. ULONG) or struct or global procedure.
struct HSHT_TYPETABLE
{
	unsigned long	offPreviousTable;
	unsigned long	hashNumber;
	unsigned long	iNameType;
	unsigned long	type;
	unsigned long	N1;
};

//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   SYMD (Symbol data)
//
//   This segment must finish on DWORD boundary, so you must add NULL bytes at the end.
//
//   -----------------------
//   |SYMD Header          |
//   ----------------------- |
//   |SegmentData Header   | |
//   - - - - - - - - - - - - |
//   |SegmentData          | |
//   |...                  | |- subSection
//   ----------------------- |
//   |VariablesData        | |
//   |...                  | |
//   ----------------------- |
//   |Source Files Def.    | |
//   ----------------------- |
//
//   SegmentData:
//   -----------------------
//   |1. SegmentData table |
//   -----------------------
//   |2. SegmentData table |
//   -----------------------
//   | ....                |
//   -----------------------
//
//   VariableData(seg1):
//   -------------------------------
//   |Procedures Def.              |
//   -------------------------------
//   |LocalVariables Def.          |
//   -------------------------------
//   |SourceCode Line Offsets  Def.|
//   -------------------------------
//   |Source Sections Def.         |
//   -------------------------------
//   |Variable/Label/Procedure     |
//   |Offsets in Program Def.      |
//   -------------------------------
//
//   VariableData(seg2):
//   -------------------------------
//   |Procedures Def.              |
//   -------------------------------
//   |LocalVariables Def.          |
//   -------------------------------
//   |SourceCode Line Offsets  Def.|
//   -------------------------------
//   |Source Sections Def.         |
//   -------------------------------
//   |Variable/Label/Procedure     |
//   |Offsets in Program Def.      |
//   -------------------------------
//   .
//   .
//   .
//
//
//   ------------------------------------------------------------------------------
//   SYMD_header:
//   offset    data     name
//   0         ULONG    SYMD(string)
//   4         ULONG    sectionLength
//   8         ULONG    offSegmentData_header
//   C       8*ULONG    NULL
//
//   sectionLength - Length of whole section (NULL bytes at the end are included).
//   offSegmentData_header - Offset in file to SegmentData_header.
struct SYMD_HEADER
{
	unsigned long	SYMD;
	unsigned long	sectionLength;
	unsigned long	offSegmentData_header;
	unsigned long	N1;
	unsigned long	N2;
	unsigned long	N3;
	unsigned long	N4;
	unsigned long	N5;
	unsigned long	N6;
	unsigned long	N7;
	unsigned long	N8;
};
#define SYMDs		0x444D5953

//   ------------------------------------------------------------------------------
//   SegmentData_header(subsection):
//   0         ULONG    subSectionLength
//   4         ULONG    cSourceFiles
//   8         ULONG    cSegments
//   C         *        segmentData
//
//   cSourceFiles - Number of files that contribute to source code.
//   cSegments - Number of segments that are present in SYMD.
//               *NOTICE!
//               *Ex. We have 3 segments. In first two, we have some definitions(labels/variables/whatever), but not in 3rd one,
//               *then only first two will be in SYMD. BUT if we have something defined only in third one, then
//               *we must include all 3 segments (but first two will have everything zero(well almost).
struct SEGMENTDATA_HEADER
{
	unsigned long	subSectionLength;
	unsigned long	cSourceFiles;
	unsigned long	cSegments;
};

//   ------------------------------------------------------------------------------
//   SegmentData Table:
//   0         SHORT    nSeg
//   2         ULONG    iNameSegment
//   6         ULONG    NULL
//   A         ULONG    physSize
//   E         ULONG    offProcDef
//   12        ULONG    cProcedures
//   16        ULONG    offLVarDef
//   1A        ULONG    offSCLineDef
//   1E        ULONG    offVLPDef
//   22        ULONG    cVLP
//   26        ULONG    offVLPOffsets
//   2A        ULONG    offSourceSDef
//   2E        ULONG    cSourceSec
//   32        ULONG    offSCLineDef(this variable is probably for something else, the real offSCLineDef is defined after offLVarDef)
//
//   nSeg - Segment number. (Normaly 1-CODE, 2-DATA)
//   iNameSegment - Index name in STTB of this segment.
//   physSize - Size of the segment in the program.(If you make a PE header dump you'll see this numbers quite clearly.)
//
//   offProcDef - Offset to Procedures Definitions from start of it's SegmentData Table.
//   cProcedure - Number of procedures defined in Procedures Definitions.
//   offLVarDef - Offset to LocalVariables Definition from start of it's SegmentData Table.
//   offSCLineDef - Offset to SourceCode Line Offset Definition from start of it's SegmentData Table.
//
//   offVLPDef - Offset to Variable/Label/Procedure tables from start of it's SegmentData Table.
//   cVLP - Number of Variables/Labels/Procedures in Variable/Label/Procedure Offset Definitions section.
//          If there aren't any in this segment, than this number is -1.
//   offVLPOffsets - Offset to VLP_Tables offsets from start of it's SegmentData Table.
//
//   offSourceSDef - Offset to Source Sections Definition from start of it's SegmentData Table.
//   cSourceSec - Number of Source Section Tables in Source Sections Definition.
//
//   Notice!
//   If some offset variable don't have it's section than they point to the first usefull section.
struct SEGMENTDATA
{
	unsigned short	nSeg;
	unsigned long	iNameSegment;
	unsigned long	N1;
	unsigned long	physSize;
	unsigned long	offProcDef;
	unsigned long	cProcedures;
	unsigned long	offLVarDef;
	unsigned long	offSCLineDef;
	unsigned long	offVLPDef;
	unsigned long	cVLP;
	unsigned long	offVLPOffsets;
	unsigned long	offSourceSDef;
	unsigned long	cSourceSec;
	unsigned long	offSCLineDef2;
};

//   ------------------------------------------------------------------------------
//   variablesData:
//
//   -------------------------------
//   |Procedures Def.              |
//   -------------------------------
//   |LocalVariables Def.          |  <=you can get number of them from procedures def. (sum)
//   -------------------------------
//   |SourceCode Line Offsets  Def.|
//   -------------------------------
//   |Source Sections Def.         |
//   -------------------------------
//   |Variable/Label/Procedure     |
//   |Offsets Def.                 |
//   -------------------------------
//   |Source Files Def.            |
//   -------------------------------
//

//   ------------------------------------------------
//   Procedures Definitions:
//   This section defines ALL procedures in the program.
//
//offset    data      name
//   0         ULONG     offStartProc
//   4         ULONG     offEndProc
//   8         ULONG     offLocalVariables
//   C         ULONG     cLocalVariables
//   10        ULONG     NULL
//   14        ULONG     NULL
//   18        ULONG     -1
//
//   offStartProc - Offset in CODE segment to beginning of the procedure.
//   offEndProc - Offset in CODE segment to the last byte in procedure.
//                (OR offStartOfNextProc-1 )
//   offLocalVariables - Offset to procedure local variables in LocalVariables Definition section.
//   cLocalVariables - Number of local variables. (Variables push-ed before calling the procedure are defined as local too.)
//
//   Notice!
//   'Local sections' from Main: to the first PROC definiton must have their own 'PROC' definition.
//   *ex.
//   *Main:
//   *	call GetModuleHandle, NULL
//   *	jmp	@JumpSetOne
//   *	nop
//   *@JumpSetOne:
//   *	call	GetOnly, offset Only, offset NextData
//   *	call	ExitProcess, NULL
//   *
//   *GetOnly PROC pOnly:POINTER, pNextData:POINTER
//   *...
//   *
//   *1.section: from Main: -> @JumpSetOne:
//   *2.section: from @JumpSetOne -> GetOnly PROC ...
//   *
struct SEGDATA_PROCEDURE
{
	unsigned long	offStartProc;
	unsigned long	offEndProc;
	unsigned long	offLocalVariables;
	unsigned long	cLocalVariables;
	unsigned long	N1;
	unsigned long	N2;
	unsigned long	M1;
};

//   ------------------------------------------------
//   LocalVariables Definition:
//   This section defines ALL local variables.
//   Variables push-ed before calling the procedure are defined as local too.
//
//   Local variable table:
//   offset    data      name
//   0         SHORT     10h
//   2         SHORT     1h   => Procedure Local Variable (look in VLP section for more details)
//   4         ULONG     type
//   8         ULONG     iNameLocal
//   C         ULONG     offLocal
//
//   type -  Type of variable.
//   iNameLocal - Index name in STTB.
//   offLocal - Signed offset relative to EBP(- for localy defined, + for pushed).
//
//   Structure is defined in VLP sectionn. (struct SEGDATA_VLPTABLE)

//   ------------------------------------------------
//   SourceCode Line Offset Definition:
//   This section defines ALL commands that are present in a program.
//   It doesn't matter if your program has multiple source files, when
//   program is assembled source CODEs are one behind another.
//
//   Source Line Table:
//   offset    data      name
//   0         ULONG     offInCode
//   4         ULONG     lineNumber
//
//   offInCode - Offset in CODE segment of specific command.
//   lineNumber - Line number where command begins.
//
//   *ex.
//   *
//   *offsetInCode   lineNumber
//   * 0       10  |
//   * 7       11  |
//   * 9       12  |
//   * A       13  | -> first file with source CODE
//   * B       15  |
//   * 1A      16  |
//   * 1F      17  |
//   * 29      18  /
//   * 2A      C   |
//   * 2B      D   |
//   * 3A      E   |
//   * 41      F   | -> second file with source CODE
//   * 48      10  |
//   * 4B      11  |
//   * 4D      12  /
//
//   For more detailed explanation read sstSrcModule in 'Borland_subSectionTypes.txt'
//
//   !!(This sections is only if cProcedures is not zero.)
struct SEGDATA_SOURCELINES
{
	unsigned long	offInCode;
	unsigned long	lineNumber;
};

//   ------------------------------------------------
//   Source Sections Definition:
//   This section defines ALL sections in CODE segment.
//   Every CODE section can be one source file.
//
//   Source Section Table:
//   offset    data      name
//   0         ULONG     offStartSourceSection
//   4         ULONG     offEndSourceSection
//   8         ULONG     offSourceLine
//   C         ULONG     cLinesTables
//   10        ULONG     offInSFDef
//
//   offStartSourceSection - Offset to beginning of source section in CODE segment.
//   offEndSourceSection - Offset to ending of source section in CODE segment.
//   offSourceLine - Offset to segments's source line tables in SourceCode Line Offsets Definition.
//   cLineTables - Number of source line tables.
//   offInSFDef - Offset to sections sourceFiles table in Source Files Definitions.
struct SEGDATA_SOURCESECTION
{
	unsigned long	offStartSourceSection;
	unsigned long	offEndSourceSection;
	unsigned long	offSourceLine;
	unsigned long	cLineTables;
	unsigned long	offInSFDef;
};

//   ------------------------------------------------
//   Variable/Label/Procedure Offset Definitions:
//
//   --------------------------------
//   |1.Seg Var.././.. Tables       |
//   --------------------------------
//   |1.Seg offsets to VLP Tables   |
//   --------------------------------
//
//   Variable/Label/Procedure Table:
//   offset    data      name
//   0         SHORT     10h
//   2         SHORT     tableType
//   4         ULONG     type
//   8         ULONG     iNameVLP
//   C         ULONG     offVLP
//
//   tableType - Defines table type.
//               *1 Procedure Local Variable (used in 'Local variable table')
//               *4 Label
//               *5 Variable
//               *6 Global Variable
//               *7 Local Procedure
//               *8 Global Procedure
//               *9 Import Descriptor (Don't take me for my word with this one.)
//   type - Defines Var.././.. type.
//          For local procedure this one defines an empty ARGLIST type (in NM Types).
//          For global procedure this one defines ARGLIST type (in NM Types) appropriate to the number and type of pushed variables.
//
//   iNameVLP - Index name in STTB of Variable or Label or Procedure.
//   offVLP - Offset in segment.
//
struct SEGDATA_VLPTABLE
{
	unsigned short	ten;
	unsigned short	tableType;
	unsigned long	type;
	unsigned long	iNameVLP;
	unsigned long	offVLP;
};
#define TT_LOCALV		0x1
#define TT_LABEL		0x4
#define TT_VARIABLE		0x5
#define TT_GLOBALV		0x6
#define TT_LOCALP		0x7
#define TT_GLOBALP		0x8
#define TT_IMPORTD		0x9

//   VLP offsets:
//   offset    data      name
//   0         ULONG     offToVLPTable1
//   4         ULONG     offToVLPTable2
//   *         ULONG     *
//
//   offToVLPTableX - Offset to VLP table from start of VLP section. So NULL means at the beginning of VLP section.
//
//   There are cVLP offsets!
//
//
//   Well when loader32 makes nms file this number are mixed (otVLPT4, ..1, ..8, or whatever).
//   So I didn't find any pattern in those numbers.
//   In IDA2NMS this numbers will be from offToVLPTable1 forward.


//   ------------------------------------------------
//   Source Files Definitions:
//   This section defines ALL files with source code.
//
//   sourceFiles Table:
//   offset    data      name
//   0         ULONG     iNameSource
//   4         ULONG     offSource
//   8         ULONG     sourceLength
//   C         ULONG     NULL
//   10        ULONG     NULL
//
//
//   iNameSource - Index name in STTB of source file.
//   offSource - Because all files with source code are put together to one big text section.
//               This offset must define where in this big text section starts specified file.
//   sourceLength - Length of source code file.
struct SEGDATA_SOURCEFILE
{
	unsigned long	iNameSource;
	unsigned long	offSource;
	unsigned long	sourceLength;
	unsigned long	N1;
	unsigned long	N2;
};


//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   FPOD
//
//   FPOD_header:
//   offset  data     name
//   0       ULONG    FPOD(string)
//   4       ULONG    sectionLength
//   8     A*ULONG    NULL
struct FPOD_HEADER
{
	unsigned long	FPOD;
	unsigned long	sectionLength;
	unsigned long	N1;
	unsigned long	N2;
	unsigned long	N3;
	unsigned long	N4;
	unsigned long	N5;
	unsigned long	N6;
	unsigned long	N7;
	unsigned long	N8;
	unsigned long	N9;
	unsigned long	NA;
};
#define FPODs		0x444F5046


//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   SRCP (Source copy)
//
//   SRCP_header:
//   offset  data     name
//   0       ULONG    SRCP(string)
//   4       ULONG    sectionLength
//   8       ULONG    offSourceFiles
//   C     2*ULONG    NULL
//
//   sectionLength - Length of SRCP section.
//   offSourceLength - Offset in file to source code files. They are one after another without any free byte.
//                     If source files are not in nms file than this one is 0.
//
//   NOTICE!
//   Because file must finish on DWORD boundary you must add zeros at the end of source code text.
struct SRCP_HEADER
{
	unsigned long	SRCP;
	unsigned long	sectionLength;
	unsigned long	offSourceFiles;
	unsigned long	N1;
	unsigned long	N2;
};
#define SRCPs		0x50435253

//   -----------------------------------------------------------------------------------------------------------
//   -----------------------------------------------------------------------------------------------------------
//   GTYP (Global types)
//
//   GTYP_header:
//   offset  data     name
//   0       ULONG    GTYP(string)
//   4       ULONG    sectionLength
//   8       ULONG    offNMTP
//   C       ULONG    offSTTB
//   10      ULONG    offTYTB
//   14      ULONG    offHSHT
//   18    2*ULONG    NULL
//
//   sectionLength - Length of GTYP section.
//   offNMTP - Offset in file to NMTP.
//   offSTTB - Offset in file to STTB.
//   offTYTB - Offset in file to TYTB.
//   offHSHT - Offset in file to HSHT.
struct GTYP_HEADER
{
	unsigned long	GTYP;
	unsigned long	sectionLength;
	unsigned long	offNMTP;
	unsigned long	offSTTB;
	unsigned long	offTYTB;
	unsigned long	offHSHT;
	unsigned long	N1;
	unsigned long	N2;
};
#define GTYPs		0x50595447


#endif	//_NM32_
