Author Topic: KPCR structure  (Read 2012 times)

guga

  • Moderator
  • Member
  • *****
  • Posts: 826
  • Assembly is a state of art.
    • RosAsm
KPCR structure
« on: January 14, 2016, 05:07:20 AM »
WDM KPCR structure is a true MONSTER !!!

I can´t even paste the code here because it is really huge !

So, i´m attaching in txt format.

I hope the structure is ok. It took me hours to finish tat crap and yet, i don´t know if all of it´s members are properly listed (with the size of the data). I found references for it, but they seems to vary. So i tried to make it the most complete as possible.

I gave a try in a wmd header i had here, but it is different from what i found so Far.

This beats have something around 1756 members !!!

How´s that possible that someone in his sane mind build a structure that huge ???? No wonder M$ internal code is a pile of S$@#$@%?@.... :icon_mrgreen:

Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Grincheux

  • Member
  • ***
  • Posts: 328
  • Never be pleased, Always improve
    • Asm for fun
Re: KPCR structure
« Reply #1 on: January 14, 2016, 06:00:00 AM »
Who would like to initialize such a monster? :greenclp:
Kenavo (Bye)
----------------------
Asm for Fun
My Links
"La garde meurt mais ne rend pas"
Cambronne à Waterloo

sinsi

  • Member
  • ****
  • Posts: 996
Re: KPCR structure
« Reply #2 on: January 14, 2016, 07:03:29 AM »

typedef struct _KPCR
{
     union
     {
          NT_TIB NtTib;
          struct
          {
               PEXCEPTION_REGISTRATION_RECORD Used_ExceptionList;
               PVOID Used_StackBase;
               PVOID Spare2;
               PVOID TssCopy;
               ULONG ContextSwitches;
               ULONG SetMemberCopy;
               PVOID Used_Self;
          };
     };
     PKPCR SelfPcr;
     PKPRCB Prcb;
     UCHAR Irql;
     ULONG IRR;
     ULONG IrrActive;
     ULONG IDR;
     PVOID KdVersionBlock;
     PKIDTENTRY IDT;
     PKGDTENTRY GDT;
     PKTSS TSS;
     WORD MajorVersion;
     WORD MinorVersion;
     ULONG SetMember;
     ULONG StallScaleFactor;
     UCHAR SpareUnused;
     UCHAR Number;
     UCHAR Spare0;
     UCHAR SecondLevelCacheAssociativity;
     ULONG VdmAlert;
     ULONG KernelReserved[14];
     ULONG SecondLevelCacheSize;
     ULONG HalReserved[16];
     ULONG InterruptMode;
     UCHAR Spare1;
     ULONG KernelReserved2[17];
     KPRCB PrcbData;
} KPCR, *PKPCR;
I can walk on water but stagger on beer.

guga

  • Moderator
  • Member
  • *****
  • Posts: 826
  • Assembly is a state of art.
    • RosAsm
Re: KPCR structure
« Reply #3 on: January 14, 2016, 07:41:13 AM »
Yup... :t

Now.....take a look at KPRCB structure  :icon_mrgreen: :icon_mrgreen:

That´s the problem with those sort of tags inside a structure. It mislead the user to think it is short, whereas, in fact, it can be unreadable when analyzing it deeper.

Code: [Select]
          typedef struct _KPRCB                                                   // 245 elements, 0x3628 bytes (sizeof)
           {
/*0x000*/      UINT16       MinorVersion;
/*0x002*/      UINT16       MajorVersion;
/*0x004*/      struct _KTHREAD* CurrentThread;
/*0x008*/      struct _KTHREAD* NextThread;
/*0x00C*/      struct _KTHREAD* IdleThread;
/*0x010*/      UINT8        LegacyNumber;
/*0x011*/      UINT8        NestingLevel;
/*0x012*/      UINT16       BuildType;
/*0x014*/      CHAR         CpuType;
/*0x015*/      CHAR         CpuID;
               union                                                               // 2 elements, 0x2 bytes (sizeof)
               {
/*0x016*/          UINT16       CpuStep;
                   struct                                                          // 2 elements, 0x2 bytes (sizeof)
                   {
/*0x016*/              UINT8        CpuStepping;
/*0x017*/              UINT8        CpuModel;
                   };
               };
/*0x018*/      struct _KPROCESSOR_STATE ProcessorState;                            // 2 elements, 0x320 bytes (sizeof)
/*0x338*/      ULONG32      KernelReserved[16];
/*0x378*/      ULONG32      HalReserved[16];
/*0x3B8*/      ULONG32      CFlushSize;
/*0x3BC*/      UINT8        CoresPerPhysicalProcessor;
/*0x3BD*/      UINT8        LogicalProcessorsPerCore;
/*0x3BE*/      UINT8        PrcbPad0[2];
/*0x3C0*/      ULONG32      MHz;
/*0x3C4*/      UINT8        CpuVendor;
/*0x3C5*/      UINT8        GroupIndex;
/*0x3C6*/      UINT16       Group;
/*0x3C8*/      ULONG32      GroupSetMember;
/*0x3CC*/      ULONG32      Number;
/*0x3D0*/      UINT8        PrcbPad1[72];
/*0x418*/      struct _KSPIN_LOCK_QUEUE LockQueue[17];
/*0x4A0*/      struct _KTHREAD* NpxThread;
/*0x4A4*/      ULONG32      InterruptCount;
/*0x4A8*/      ULONG32      KernelTime;
/*0x4AC*/      ULONG32      UserTime;
/*0x4B0*/      ULONG32      DpcTime;
/*0x4B4*/      ULONG32      DpcTimeCount;
/*0x4B8*/      ULONG32      InterruptTime;
/*0x4BC*/      ULONG32      AdjustDpcThreshold;
/*0x4C0*/      ULONG32      PageColor;
/*0x4C4*/      UINT8        DebuggerSavedIRQL;
/*0x4C5*/      UINT8        NodeColor;
/*0x4C6*/      UINT8        PrcbPad20[2];
/*0x4C8*/      ULONG32      NodeShiftedColor;
/*0x4CC*/      struct _KNODE* ParentNode;
/*0x4D0*/      ULONG32      SecondaryColorMask;
/*0x4D4*/      ULONG32      DpcTimeLimit;
/*0x4D8*/      ULONG32      PrcbPad21[2];
/*0x4E0*/      ULONG32      CcFastReadNoWait;
/*0x4E4*/      ULONG32      CcFastReadWait;
/*0x4E8*/      ULONG32      CcFastReadNotPossible;
/*0x4EC*/      ULONG32      CcCopyReadNoWait;
/*0x4F0*/      ULONG32      CcCopyReadWait;
/*0x4F4*/      ULONG32      CcCopyReadNoWaitMiss;
/*0x4F8*/      LONG32       MmSpinLockOrdering;
/*0x4FC*/      LONG32       IoReadOperationCount;
/*0x500*/      LONG32       IoWriteOperationCount;
/*0x504*/      LONG32       IoOtherOperationCount;
/*0x508*/      union _LARGE_INTEGER IoReadTransferCount;                           // 4 elements, 0x8 bytes (sizeof)
/*0x510*/      union _LARGE_INTEGER IoWriteTransferCount;                          // 4 elements, 0x8 bytes (sizeof)
/*0x518*/      union _LARGE_INTEGER IoOtherTransferCount;                          // 4 elements, 0x8 bytes (sizeof)
/*0x520*/      ULONG32      CcFastMdlReadNoWait;
/*0x524*/      ULONG32      CcFastMdlReadWait;
/*0x528*/      ULONG32      CcFastMdlReadNotPossible;
/*0x52C*/      ULONG32      CcMapDataNoWait;
/*0x530*/      ULONG32      CcMapDataWait;
/*0x534*/      ULONG32      CcPinMappedDataCount;
/*0x538*/      ULONG32      CcPinReadNoWait;
/*0x53C*/      ULONG32      CcPinReadWait;
/*0x540*/      ULONG32      CcMdlReadNoWait;
/*0x544*/      ULONG32      CcMdlReadWait;
/*0x548*/      ULONG32      CcLazyWriteHotSpots;
/*0x54C*/      ULONG32      CcLazyWriteIos;
/*0x550*/      ULONG32      CcLazyWritePages;
/*0x554*/      ULONG32      CcDataFlushes;
/*0x558*/      ULONG32      CcDataPages;
/*0x55C*/      ULONG32      CcLostDelayedWrites;
/*0x560*/      ULONG32      CcFastReadResourceMiss;
/*0x564*/      ULONG32      CcCopyReadWaitMiss;
/*0x568*/      ULONG32      CcFastMdlReadResourceMiss;
/*0x56C*/      ULONG32      CcMapDataNoWaitMiss;
/*0x570*/      ULONG32      CcMapDataWaitMiss;
/*0x574*/      ULONG32      CcPinReadNoWaitMiss;
/*0x578*/      ULONG32      CcPinReadWaitMiss;
/*0x57C*/      ULONG32      CcMdlReadNoWaitMiss;
/*0x580*/      ULONG32      CcMdlReadWaitMiss;
/*0x584*/      ULONG32      CcReadAheadIos;
/*0x588*/      ULONG32      KeAlignmentFixupCount;
/*0x58C*/      ULONG32      KeExceptionDispatchCount;
/*0x590*/      ULONG32      KeSystemCalls;
/*0x594*/      ULONG32      AvailableTime;
/*0x598*/      ULONG32      PrcbPad22[2];
/*0x5A0*/      struct _PP_LOOKASIDE_LIST PPLookasideList[16];
/*0x620*/      struct _GENERAL_LOOKASIDE_POOL PPNPagedLookasideList[32];
/*0xF20*/      struct _GENERAL_LOOKASIDE_POOL PPPagedLookasideList[32];
/*0x1820*/     ULONG32      PacketBarrier;
/*0x1824*/     LONG32       ReverseStall;
/*0x1828*/     VOID*        IpiFrame;
/*0x182C*/     UINT8        PrcbPad3[52];
/*0x1860*/     VOID*        CurrentPacket[3];
/*0x186C*/     ULONG32      TargetSet;
/*0x1870*/     PVOID WorkerRoutine;
/*0x1874*/     ULONG32      IpiFrozen;
/*0x1878*/     UINT8        PrcbPad4[40];
/*0x18A0*/     ULONG32      RequestSummary;
/*0x18A4*/     struct _KPRCB* SignalDone;
/*0x18A8*/     UINT8        PrcbPad50[56];
/*0x18E0*/     struct _KDPC_DATA DpcData[2];
/*0x1908*/     VOID*        DpcStack;
/*0x190C*/     LONG32       MaximumDpcQueueDepth;
/*0x1910*/     ULONG32      DpcRequestRate;
/*0x1914*/     ULONG32      MinimumDpcRate;
/*0x1918*/     ULONG32      DpcLastCount;
/*0x191C*/     ULONG32      PrcbLock;
/*0x1920*/     struct _KGATE DpcGate;                                              // 1 elements, 0x10 bytes (sizeof)
/*0x1930*/     UINT8        ThreadDpcEnable;
/*0x1931*/     UINT8        QuantumEnd;
/*0x1932*/     UINT8        DpcRoutineActive;
/*0x1933*/     UINT8        IdleSchedule;
               union                                                               // 3 elements, 0x4 bytes (sizeof)
               {
/*0x1934*/         LONG32       DpcRequestSummary;
/*0x1934*/         INT16        DpcRequestSlot[2];
                   struct                                                          // 2 elements, 0x4 bytes (sizeof)
                   {
/*0x1934*/             INT16        NormalDpcState;
                       union                                                       // 2 elements, 0x2 bytes (sizeof)
                       {
/*0x1936*/                 UINT16       DpcThreadActive : 1;                       // 0 BitPosition
/*0x1936*/                 INT16        ThreadDpcState;
                       };
                   };
               };
/*0x1938*/     ULONG32      TimerHand;
/*0x193C*/     ULONG32      LastTick;
/*0x1940*/     LONG32       MasterOffset;
/*0x1944*/     ULONG32      PrcbPad41[2];
/*0x194C*/     ULONG32      PeriodicCount;
/*0x1950*/     ULONG32      PeriodicBias;
/*0x1954*/     UINT8        _PADDING0_[0x4];
/*0x1958*/     UINT64       TickOffset;
/*0x1960*/     struct _KTIMER_TABLE TimerTable;                                    // 2 elements, 0x1840 bytes (sizeof)
/*0x31A0*/     struct _KDPC CallDpc;                                               // 9 elements, 0x20 bytes (sizeof)
/*0x31C0*/     LONG32       ClockKeepAlive;
/*0x31C4*/     UINT8        ClockCheckSlot;
/*0x31C5*/     UINT8        ClockPollCycle;
/*0x31C6*/     UINT8        PrcbPad6[2];
/*0x31C8*/     LONG32       DpcWatchdogPeriod;
/*0x31CC*/     LONG32       DpcWatchdogCount;
/*0x31D0*/     LONG32       ThreadWatchdogPeriod;
/*0x31D4*/     LONG32       ThreadWatchdogCount;
/*0x31D8*/     LONG32       KeSpinLockOrdering;
/*0x31DC*/     ULONG32      PrcbPad70[1];
/*0x31E0*/     struct _LIST_ENTRY WaitListHead;                                    // 2 elements, 0x8 bytes (sizeof)
/*0x31E8*/     ULONG32      WaitLock;
/*0x31EC*/     ULONG32      ReadySummary;
/*0x31F0*/     ULONG32      QueueIndex;
/*0x31F4*/     struct _SINGLE_LIST_ENTRY DeferredReadyListHead;                    // 1 elements, 0x4 bytes (sizeof)
/*0x31F8*/     UINT64       StartCycles;
/*0x3200*/     UINT64       CycleTime;
/*0x3208*/     ULONG32      HighCycleTime;
/*0x320C*/     ULONG32      PrcbPad71;
/*0x3210*/     UINT64       PrcbPad72[2];
/*0x3220*/     struct _LIST_ENTRY DispatcherReadyListHead[32];
/*0x3320*/     VOID*        ChainedInterruptList;
/*0x3324*/     LONG32       LookasideIrpFloat;
/*0x3328*/     LONG32       MmPageFaultCount;
/*0x332C*/     LONG32       MmCopyOnWriteCount;
/*0x3330*/     LONG32       MmTransitionCount;
/*0x3334*/     LONG32       MmCacheTransitionCount;
/*0x3338*/     LONG32       MmDemandZeroCount;
/*0x333C*/     LONG32       MmPageReadCount;
/*0x3340*/     LONG32       MmPageReadIoCount;
/*0x3344*/     LONG32       MmCacheReadCount;
/*0x3348*/     LONG32       MmCacheIoCount;
/*0x334C*/     LONG32       MmDirtyPagesWriteCount;
/*0x3350*/     LONG32       MmDirtyWriteIoCount;
/*0x3354*/     LONG32       MmMappedPagesWriteCount;
/*0x3358*/     LONG32       MmMappedWriteIoCount;
/*0x335C*/     ULONG32      CachedCommit;
/*0x3360*/     ULONG32      CachedResidentAvailable;
/*0x3364*/     VOID*        HyperPte;
/*0x3368*/     UINT8        PrcbPad8[4];
/*0x336C*/     UINT8        VendorString[13];
/*0x3379*/     UINT8        InitialApicId;
/*0x337A*/     UINT8        LogicalProcessorsPerPhysicalProcessor;
/*0x337B*/     UINT8        PrcbPad9[5];
/*0x3380*/     ULONG32      FeatureBits;
/*0x3384*/     UINT8        _PADDING1_[0x4];
/*0x3388*/     union _LARGE_INTEGER UpdateSignature;                               // 4 elements, 0x8 bytes (sizeof)
/*0x3390*/     UINT64       IsrTime;
/*0x3398*/     UINT64       RuntimeAccumulation;
/*0x33A0*/     struct _PROCESSOR_POWER_STATE PowerState;                           // 27 elements, 0xC8 bytes (sizeof)
/*0x3468*/     struct _KDPC DpcWatchdogDpc;                                        // 9 elements, 0x20 bytes (sizeof)
/*0x3488*/     struct _KTIMER DpcWatchdogTimer;                                    // 5 elements, 0x28 bytes (sizeof)
/*0x34B0*/     VOID*        WheaInfo;
/*0x34B4*/     VOID*        EtwSupport;
/*0x34B8*/     union _SLIST_HEADER InterruptObjectPool;                            // 4 elements, 0x8 bytes (sizeof)
/*0x34C0*/     union _SLIST_HEADER HypercallPageList;                              // 4 elements, 0x8 bytes (sizeof)
/*0x34C8*/     VOID*        HypercallPageVirtual;
/*0x34CC*/     VOID*        VirtualApicAssist;
/*0x34D0*/     UINT64*      StatisticsPage;
/*0x34D4*/     VOID*        RateControl;
/*0x34D8*/     struct _CACHE_DESCRIPTOR Cache[5];
/*0x3514*/     ULONG32      CacheCount;
/*0x3518*/     ULONG32      CacheProcessorMask[5];
/*0x352C*/     struct _KAFFINITY_EX PackageProcessorSet;                           // 4 elements, 0xC bytes (sizeof)
/*0x3538*/     ULONG32      PrcbPad91[1];
/*0x353C*/     ULONG32      CoreProcessorSet;
/*0x3540*/     struct _KDPC TimerExpirationDpc;                                    // 9 elements, 0x20 bytes (sizeof)
/*0x3560*/     ULONG32      SpinLockAcquireCount;
/*0x3564*/     ULONG32      SpinLockContentionCount;
/*0x3568*/     ULONG32      SpinLockSpinCount;
/*0x356C*/     ULONG32      IpiSendRequestBroadcastCount;
/*0x3570*/     ULONG32      IpiSendRequestRoutineCount;
/*0x3574*/     ULONG32      IpiSendSoftwareInterruptCount;
/*0x3578*/     ULONG32      ExInitializeResourceCount;
/*0x357C*/     ULONG32      ExReInitializeResourceCount;
/*0x3580*/     ULONG32      ExDeleteResourceCount;
/*0x3584*/     ULONG32      ExecutiveResourceAcquiresCount;
/*0x3588*/     ULONG32      ExecutiveResourceContentionsCount;
/*0x358C*/     ULONG32      ExecutiveResourceReleaseExclusiveCount;
/*0x3590*/     ULONG32      ExecutiveResourceReleaseSharedCount;
/*0x3594*/     ULONG32      ExecutiveResourceConvertsCount;
/*0x3598*/     ULONG32      ExAcqResExclusiveAttempts;
/*0x359C*/     ULONG32      ExAcqResExclusiveAcquiresExclusive;
/*0x35A0*/     ULONG32      ExAcqResExclusiveAcquiresExclusiveRecursive;
/*0x35A4*/     ULONG32      ExAcqResExclusiveWaits;
/*0x35A8*/     ULONG32      ExAcqResExclusiveNotAcquires;
/*0x35AC*/     ULONG32      ExAcqResSharedAttempts;
/*0x35B0*/     ULONG32      ExAcqResSharedAcquiresExclusive;
/*0x35B4*/     ULONG32      ExAcqResSharedAcquiresShared;
/*0x35B8*/     ULONG32      ExAcqResSharedAcquiresSharedRecursive;
/*0x35BC*/     ULONG32      ExAcqResSharedWaits;
/*0x35C0*/     ULONG32      ExAcqResSharedNotAcquires;
/*0x35C4*/     ULONG32      ExAcqResSharedStarveExclusiveAttempts;
/*0x35C8*/     ULONG32      ExAcqResSharedStarveExclusiveAcquiresExclusive;
/*0x35CC*/     ULONG32      ExAcqResSharedStarveExclusiveAcquiresShared;
/*0x35D0*/     ULONG32      ExAcqResSharedStarveExclusiveAcquiresSharedRecursive;
/*0x35D4*/     ULONG32      ExAcqResSharedStarveExclusiveWaits;
/*0x35D8*/     ULONG32      ExAcqResSharedStarveExclusiveNotAcquires;
/*0x35DC*/     ULONG32      ExAcqResSharedWaitForExclusiveAttempts;
/*0x35E0*/     ULONG32      ExAcqResSharedWaitForExclusiveAcquiresExclusive;
/*0x35E4*/     ULONG32      ExAcqResSharedWaitForExclusiveAcquiresShared;
/*0x35E8*/     ULONG32      ExAcqResSharedWaitForExclusiveAcquiresSharedRecursive;
/*0x35EC*/     ULONG32      ExAcqResSharedWaitForExclusiveWaits;
/*0x35F0*/     ULONG32      ExAcqResSharedWaitForExclusiveNotAcquires;
/*0x35F4*/     ULONG32      ExSetResOwnerPointerExclusive;
/*0x35F8*/     ULONG32      ExSetResOwnerPointerSharedNew;
/*0x35FC*/     ULONG32      ExSetResOwnerPointerSharedOld;
/*0x3600*/     ULONG32      ExTryToAcqExclusiveAttempts;
/*0x3604*/     ULONG32      ExTryToAcqExclusiveAcquires;
/*0x3608*/     ULONG32      ExBoostExclusiveOwner;
/*0x360C*/     ULONG32      ExBoostSharedOwners;
/*0x3610*/     ULONG32      ExEtwSynchTrackingNotificationsCount;
/*0x3614*/     ULONG32      ExEtwSynchTrackingNotificationsAccountedCount;
/*0x3618*/     struct _CONTEXT* Context;
/*0x361C*/     ULONG32      ContextFlags;
/*0x3620*/     struct _XSAVE_AREA* ExtendedState;
/*0x3624*/     UINT8        _PADDING2_[0x4];
           }KPRCB, *PKPRCB;

PPNPagedLookasideList for example is a array formed with 32 structures "GENERAL_LOOKASIDE_POOL"

All of this "hidden" tags don´t represent the real size and format of the structure. They are mainly "shortcuts" to what the structure really is and how big is it.

There´s no such a thing as a GENERAL_LOOKASIDE_POOL data size in assembly. It is a structure formed with XXXX elements of different sizes (dword, word etc)

As you can see, only KPRCB has a size of, at least, 0x3628 (13864) bytes !!!

This is a concept we don´t use in RosAsm (and perhaps i wont´implement such a thing so soon..or... never  :icon_mrgreen: ). It is better for the user actually knows how is his data chain formed, instead having things hidden or stored in other files (headers etc) from where he may or not have them (On this case, for example, even M$ header is not accurate in earlier versions. Nevertheless, the structure remains the same just added more bytes ahead).

Of course, it may be easier to read, but it does "masks" the real thing.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Re: KPCR structure
« Reply #4 on: January 14, 2016, 02:32:39 PM »
You are aware of this Matt Suiche article, I suppose?
Code: [Select]
KPCR STRUCT
 Used_ExceptionList PEXCEPTION_REGISTRATION_RECORD <>
 Used_StackBase PVOID ?
 Spare2    PVOID ?
 TssCopy    PVOID ?
 ContextSwitches ULONG ?
 SetMemberCopy ULONG ?
 Used_Self PVOID ?
 ENDS
 ENDS
 SelfPcr    PKPCR <>
 Prcb      PKPRCB <>
 Irql      UCHAR ?
 IRR        ULONG ?
 IrrActive ULONG ?
 IDR        ULONG ?
 KdVersionBlock PVOID ?
 IDT        PKIDTENTRY <>
 GDT        PKGDTENTRY <>
 TSS        PKTSS <>
 MajorVersion WORD ?
 MinorVersion WORD ?
 SetMember ULONG ?
 StallScaleFactor ULONG ?
 SpareUnused UCHAR ?
 Number    UCHAR ?
 Spare0    UCHAR ?
 SecondLevelCacheAssociativity UCHAR ?
 VdmAlert  ULONG ?
 KernelReserved ULONG 14 dup(?)
 SecondLevelCacheSize ULONG ?
 HalReserved ULONG 16 dup(?)
 InterruptMode ULONG ?
 Spare1    UCHAR ?
 KernelReserved2 ULONG 17 dup(?)
 PrcbData  KPRCB <>
KPCR ENDS

guga

  • Moderator
  • Member
  • *****
  • Posts: 826
  • Assembly is a state of art.
    • RosAsm
Re: KPCR structure
« Reply #5 on: January 14, 2016, 03:39:16 PM »
Hi Jochen.

Didnt read this particular site, but it seems that the structure was modified again.

The one i have is bigger (Windows10 perhaps ?) I posted on another thread the links i found containing the structure. Here on the last post (the last msg that i send to Dave)
http://masm32.com/board/index.php?topic=4962.msg53975;topicseen#msg53975
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com