Author Topic: Visual Studio C++: inline assembly to C++  (Read 666 times)

flashcoder

  • Regular Member
  • *
  • Posts: 20
Visual Studio C++: inline assembly to C++
« on: March 20, 2017, 11:06:06 AM »
Hello,

Knowing that inline assembly __asm not is supported in Visual Studio for x64 projects i decided that the better solution can be a translation of inline assembly to C++.

But my knowledge is very little with Assembly.

Then someone could help me with this?

Here is the code ( this program is a Unhooker to Apis Messages ) compiled with VS2012 Ultimate:

EnumWindowsHookEx.cpp

Code: [Select]
// EnumWindowsHookEx.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "EnumWindowsHooks.h"

#pragma comment(lib, "ntdll")

int __cdecl main(int argc, char **argv)
{
NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;

PVOID ImageBase;
ULONG DllCharacteristics = 0;
PVOID User32InitializeImmEntryTable = NULL;

UNICODE_STRING DllName;
ANSI_STRING ProcedureName;

ULONG i;
ULONG UserDelta = 0;
ULONG HandleEntries = 0;

SHARED_INFO *SharedInfo = NULL;
HANDLE_ENTRY *UserHandleTable = NULL;
HOOK *HookInfo = NULL;


__try
{
system("cls");


RtlInitUnicodeString(
&DllName,
L"user32");

NtStatus = LdrLoadDll(
NULL,                // DllPath
&DllCharacteristics, // DllCharacteristics
&DllName,            // DllName
&ImageBase);         // DllHandle

if(NtStatus == STATUS_SUCCESS)
{
RtlInitAnsiString(
&ProcedureName,
"User32InitializeImmEntryTable");

NtStatus = LdrGetProcedureAddress(
ImageBase,                               // DllHandle
&ProcedureName,                          // ProcedureName
0,                                       // ProcedureNumber OPTIONAL
(PVOID*)&User32InitializeImmEntryTable); // ProcedureAddress

if(NtStatus == STATUS_SUCCESS)
{
__asm
{
       mov esi, User32InitializeImmEntryTable
test esi, esi
jz __exit2
mov ecx, 0x80

__loop:
       dec ecx
test ecx, ecx
jz __exit1

lodsb
cmp al, 0x50
jnz __loop

lodsb
cmp al, 0x68
jnz __loop

lodsd
mov SharedInfo, eax

jmp __exit2

__exit1:
mov SharedInfo, ecx

__exit2:
sub eax, eax
mov eax, fs:[eax+0x18]
lea eax, [eax+0x06CC]
mov eax, [eax+0x001C]
mov UserDelta, eax
}

HandleEntries = *((ULONG *)((ULONG)SharedInfo->ServerInfo + 8));

printf(
" +--------------------------------------------------------------------+\n"
" | SHARED_INFO - %.8X                                             |\n"
" +--------------------------------------------------------------------+\n"
" | ServerInfo - %.8X                                              |\n"
" | HandleEntryList - %.8X                                         |\n"
" | HandleEntries - %.8X                                           |\n"
" | DisplayInfo - %.8X                                             |\n"
" | SharedDelta - %.8X                                             |\n"
" | UserDelta - %.8X                                               |\n"
" +--------------------------------------------------------------------+\n\n",
SharedInfo,
SharedInfo->ServerInfo,
SharedInfo->HandleEntryList,
HandleEntries,
SharedInfo->DisplayInfo,
SharedInfo->SharedDelta,
UserDelta);

UserHandleTable = (HANDLE_ENTRY *)SharedInfo->HandleEntryList;

for(i=0; i<HandleEntries; i++)
{
if(UserHandleTable[i].Type == TYPE_HOOK)
{
__try
{
HookInfo = (HOOK *)((ULONG)UserHandleTable[i].Head - UserDelta);

printf(
" +--------------------------------------------------------------------+\n"
" | HOOK - %.8X                                                    |\n"
" +--------------------------------------------------------------------+\n"
" | Handle - %.8X                                                  |\n"
" | LockObj - %.8X                                                 |\n"
" | ThreadInfo- %.8X                                               |\n"
" | Desktop1 - %.8X                                                |\n"
" | Self - %.8X                                                    |\n"
" | NextHook - %.8X                                                |\n"
" | HookType - %.8X                                                |\n"
" | FunctionAddress - %.8X                                         |\n"
" | Flags - %.8X                                                   |\n"
" | ModuleHandle - %.8X                                            |\n"
" | Hooked - %.8X                                                  |\n"
" | Desktop2 - %.8X                                                |\n"
" +--------------------------------------------------------------------+\n\n",
(ULONG)UserHandleTable[i].Head - UserDelta,
HookInfo->Handle,
HookInfo->LockObj,
HookInfo->ThreadInfo,
HookInfo->Desktop1,
HookInfo->Self,
HookInfo->NextHook,
HookInfo->HookType,
HookInfo->FunctionAddress,
HookInfo->Flags,
HookInfo->ModuleHandle,
HookInfo->Hooked,
HookInfo->Desktop2);

UnhookWindowsHookEx((HHOOK)HookInfo->Handle);
}
__except(EXCEPTION_EXECUTE_HANDLER) {}
}
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf(">> main - %.8X\n", GetExceptionCode());

//return GetExceptionCode();
}

system("pause");

return FALSE;
}

EnumWindowsHooks.h

Code: [Select]
#ifndef __ENUM_WINDOWS_HOOKS__
#define __ENUM_WINDOWS_HOOKS__

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define IMP_VOID __declspec(dllimport) VOID __stdcall
#define IMP_SYSCALL __declspec(dllimport) NTSTATUS __stdcall

#define STATUS_SUCCESS 0x00000000
#define STATUS_UNSUCCESSFUL 0xC0000001
#define STATUS_INVALID_PARAMETER_1 0xC00000EF
#define STATUS_INVALID_PARAMETER_2 0xC00000F0

typedef struct ANSI_STRING
{
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
}
ANSI_STRING,
*PANSI_STRING,
**PPANSI_STRING;

typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
}
UNICODE_STRING,
*PUNICODE_STRING,
**PPUNICODE_STRING;

#define TYPE_FREE           0
#define TYPE_WINDOW         1
#define TYPE_MENU           2
#define TYPE_CURSOR         3
#define TYPE_SETWINDOWPOS   4
#define TYPE_HOOK           5
#define TYPE_CLIPDATA       6
#define TYPE_CALLPROC       7
#define TYPE_ACCELTABLE     8
#define TYPE_DDEACCESS      9
#define TYPE_DDECONV        10
#define TYPE_DDEXACT        11
#define TYPE_MONITOR        12
#define TYPE_KBDLAYOUT      13
#define TYPE_KBDFILE        14
#define TYPE_WINEVENTHOOK   15
#define TYPE_TIMER          16
#define TYPE_INPUTCONTEXT   17
#define TYPE_CTYPES         18
#define TYPE_GENERIC        255

#define HMINDEXBITS 0x0000FFFF
#define HMUNIQSHIFT 16
#define HMUNIQBITS 0xFFFF0000

#define MAX_HANDLE_COUNT 0x8000

typedef struct _HEAD
{
HANDLE Handle;
ULONG LockObj;
}
HEAD,
*PHEAD,
**PPHEAD;

typedef struct _HANDLE_ENTRY
{
HEAD *Head;
PVOID Owner;
UCHAR Type;
UCHAR Flags;
USHORT Unique;
}
HANDLE_ENTRY,
*PHANDLE_ENTRY,
**PPHANDLE_ENTRY;

typedef struct _SHARED_INFO
{
PVOID ServerInfo;
HANDLE_ENTRY *HandleEntryList;
PVOID DisplayInfo;
ULONG SharedDelta;
}
SHARED_INFO,
*PSHARED_INFO,
**PPSHARED_INFO;

typedef struct _HOOK
{
ULONG Handle;
ULONG LockObj;
PVOID ThreadInfo;
PVOID Desktop1;
PVOID Self;
PVOID NextHook;
LONG HookType;
PVOID FunctionAddress;
ULONG Flags;
ULONG ModuleHandle;
PVOID Hooked;
PVOID Desktop2;
}
HOOK,
*PHOOK,
**PPHOOK;

extern "C" IMP_SYSCALL LdrLoadDll
(
IN PWSTR DllPath OPTIONAL,
IN PULONG DllCharacteristics OPTIONAL,
IN PUNICODE_STRING DllName,
OUT PVOID *DllHandle
);

extern "C" IMP_SYSCALL LdrGetProcedureAddress
(
IN PVOID DllHandle,
IN PANSI_STRING ProcedureName OPTIONAL,
IN ULONG ProcedureNumber OPTIONAL,
OUT PVOID *ProcedureAddress
);

extern "C" IMP_VOID RtlInitAnsiString
(
IN OUT PANSI_STRING DestinationString,
IN PCSTR SourceString
);

extern "C" IMP_VOID RtlInitUnicodeString
(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);

#endif

LordAdef

  • Member
  • ***
  • Posts: 252
Re: Visual Studio C++: inline assembly to C++
« Reply #1 on: March 20, 2017, 01:38:42 PM »
Hi Flashcoder,

First of all, welcome to the forum.

Although I´m not the most well versed around, let me dare and say I believe the BEST solution is to create an asm file that will be working side by side to your C++ project. It´s very easy to do AND a lot better than inline. You just need to call it from the C++ world as functions.

It´s pretty much straight forward, you just need to "extern" the asm function.
There are many examples in the web, check out this one:

https://www.youtube.com/watch?v=guru397zg2g

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #2 on: March 20, 2017, 03:03:48 PM »
@LordAdef,

Thank you, but see that on code above exists 3 c++ variables used inside assembly code, are they:

User32InitializeImmEntryTable
SharedInfo
UserDelta

Then, how use these variables, stucts... on asm code from external .asm file?
On video suggested of Youtube, is showed only a simply method.

LordAdef

  • Member
  • ***
  • Posts: 252
Re: Visual Studio C++: inline assembly to C++
« Reply #3 on: March 20, 2017, 03:57:49 PM »
Hi Flash,

You must send the 3 variables to the function, defining their "sizes" in the extern declaration, in C++ world. I didn´t check the variables types, but if you have to send them as reference, "Pointers" in 32 bit masm are DWORDs, in 64 I guess they are QWORD in the masm world.

I don´t see him prototyping the asm function in the asm file, maybe you don´t need to and admit I needed to test. But if you do, it would be something like this:

AsmNirvanaFunction  PROTO   :QWORD, :QWORD, :QWORD
« Last Edit: March 20, 2017, 05:25:01 PM by LordAdef »

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #4 on: March 21, 2017, 07:17:55 AM »
Ok LordAdef,

How be should these types:

PVOID, ULONG, Struct

Code: [Select]
typedef struct _SHARED_INFO
{
PVOID ServerInfo;
HANDLE_ENTRY *HandleEntryList;
PVOID DisplayInfo;
ULONG SharedDelta;
}
SHARED_INFO,
*PSHARED_INFO,
**PPSHARED_INFO;

--------------------------------------------------

PVOID User32InitializeImmEntryTable = NULL;
ULONG UserDelta = 0;
SHARED_INFO *SharedInfo = NULL;

respectivelly from of C++ to ASM, as parameters of AsmNirvanaFunction?

adeyblue

  • Member
  • **
  • Posts: 85
    • Airesoft
Re: Visual Studio C++: inline assembly to C++
« Reply #5 on: March 21, 2017, 08:48:56 AM »
Don't bother with it, on 7x64 (at least) all the addresses are in kernel mode so you can't do anything with them when you do find the HOOKs.
Code: [Select]
EnumHooks apparently found 4437 handles
Found hook at FFFFF900C0830E20
Found hook at FFFFF900C0837610
Found hook at FFFFF900C0848840
etc..

Code: [Select]
struct tagSERVERINFO
{
ULONG srviFlags;
SIZE_T handleEntries;
};

struct tagSHAREDINFO
{
tagSERVERINFO* psi;
struct _HANDLE_ENTRY* aheList;
unsigned long HeEntrySize;
};

void EnumHooks()
{
HMODULE hUser = GetModuleHandle(L"user32.dll");
tagSHAREDINFO* pSharedData = (tagSHAREDINFO*)GetProcAddress(hUser, "gSharedInfo");
SIZE_T entrySize = pSharedData->psi->handleEntries;
printf("EnumHooks apparently found %Iu handles\n", entrySize);
TEB_7* pTeb = (TEB_7*)NtCurrentTeb();
UINT_PTR offset = pTeb->Win32ClientInfo[7];
for(ULONG i = 0; i < entrySize; ++i)
{
HANDLE_ENTRY* pHandle = &pSharedData->aheList[i];
if(pHandle->Type != TYPE_HOOK) continue;
HOOK* HookInfo = (HOOK*)(pHandle->pHead - offset);
if(HookInfo)
{
printf("Found hook at %p\n", HookInfo);
}
}
}

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #6 on: March 21, 2017, 12:53:50 PM »
@AdeyBlue,

thank you very much by code example, but here not worked, and you also not showed complete code above.

Then i completed your code like below, but not worked  :icon_confused: Comes a Access Violation in printf inside of for loop.

Code: [Select]
#include "stdafx.h"
#include <process.h>
#include <iostream>
#include <windows.h>
#include <WinNT.h>
#include "EnumWindowsHooks.h"

#pragma comment(lib, "ntdll")

using namespace std;

typedef struct _HANDLEENTRY {
PVOID   phead;
PVOID   pOwner;
BYTE    bType;
BYTE    bFlags;
WORD    wUniq;
} HANDLEENTRY, *PHANDLEENTRY;

typedef struct _SERVERINFO {
WORD            wRIPFlags;
WORD            wSRVIFlags;
WORD            wRIPPID;
WORD            wRIPError;
ULONG           cHandleEntries;
} SERVERINFO, *PSERVERINFO;

typedef struct _SHAREDINFO {
PSERVERINFO  psi;
PHANDLEENTRY aheList;
ULONG   HeEntrySize;
} SHAREDINFO, *PSHAREDINFO;

typedef struct _PEB {
    BYTE Reserved1[2];
    BYTE BeingDebugged;
    BYTE Reserved2[229];
    PVOID Reserved3[59];
    ULONG SessionId;
} PEB, *PPEB;

typedef struct _CLIENT_ID
{
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef struct _TEB
{
    NT_TIB Tib;
    PVOID EnvironmentPointer;
    CLIENT_ID Cid;
    PVOID ActiveRpcInfo;
    PVOID ThreadLocalStoragePointer;
    PPEB Peb;
    ULONG LastErrorValue;
    ULONG CountOfOwnedCriticalSections;
    PVOID CsrClientThread;
    PVOID Win32ThreadInfo;
    ULONG Win32ClientInfo[0x1F];
    PVOID WOW32Reserved;
    ULONG CurrentLocale;
    ULONG FpSoftwareStatusRegister;
    PVOID SystemReserved1[0x36];
    PVOID Spare1;
    ULONG ExceptionCode;
    ULONG SpareBytes1[0x28];
    PVOID SystemReserved2[0xA];
    ULONG GdiRgn;
    ULONG GdiPen;
    ULONG GdiBrush;
    CLIENT_ID RealClientId;
    PVOID GdiCachedProcessHandle;
    ULONG GdiClientPID;
    ULONG GdiClientTID;
    PVOID GdiThreadLocaleInfo;
    PVOID UserReserved[5];
    PVOID GlDispatchTable[0x118];
    ULONG GlReserved1[0x1A];
    PVOID GlReserved2;
    PVOID GlSectionInfo;
    PVOID GlSection;
    PVOID GlTable;
    PVOID GlCurrentRC;
    PVOID GlContext;
    NTSTATUS LastStatusValue;
    UNICODE_STRING StaticUnicodeString;
    WCHAR StaticUnicodeBuffer[0x105];
    PVOID DeallocationStack;
    PVOID TlsSlots[0x40];
    LIST_ENTRY TlsLinks;
    PVOID Vdm;
    PVOID ReservedForNtRpc;
    PVOID DbgSsReserved[0x2];
    ULONG HardErrorDisabled;
    PVOID Instrumentation[0x10];
    PVOID WinSockData;
    ULONG GdiBatchCount;
    ULONG Spare2;
    ULONG Spare3;
    ULONG Spare4;
    PVOID ReservedForOle;
    ULONG WaitingOnLoaderLock;
    PVOID StackCommit;
    PVOID StackCommitMax;
    PVOID StackReserved;
} TEB, *PTEB;

void EnumHooks()
{
HMODULE hUser = GetModuleHandle(L"user32.dll");
PSHAREDINFO  gSharedInfo=NULL;
PHANDLEENTRY aheList=NULL;
ULONG_PTR   k;
gSharedInfo = (PSHAREDINFO)GetProcAddress(hUser, "gSharedInfo");
aheList = gSharedInfo->aheList;
k = gSharedInfo->psi->cHandleEntries;
printf("EnumHooks apparently found %Iu handles\n", k);
PTEB pTeb = (PTEB)NtCurrentTeb();
UINT_PTR offset = pTeb->Win32ClientInfo[7];

for(ULONG i = 0; i < k; ++i)
{
HANDLEENTRY* pHandle = &aheList[i];
if(pHandle->bType != TYPE_HOOK) continue;
HOOK* HookInfo = (HOOK*)((PVOID*)pHandle->phead - offset);

if(HookInfo)
{
//printf("Found hook at %p\n", HookInfo);
}
}
}

« Last Edit: March 21, 2017, 02:48:26 PM by flashcoder »

TWell

  • Member
  • ****
  • Posts: 704
Re: Visual Studio C++: inline assembly to C++
« Reply #7 on: March 21, 2017, 07:55:35 PM »
It works only in native environment?
In WOW64 PHANDLEENTRY is 0 and HeEntrySize is trash? It should be sizeof(HANDLEENTRY)?
-- Tim, not a assembler programmer

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #8 on: March 21, 2017, 11:40:30 PM »
It works only in native environment?
In WOW64 PHANDLEENTRY is 0 and HeEntrySize is trash? It should be sizeof(HANDLEENTRY)?

@TWell,

here are all returned values:

Environment of test:

VS2012 Ultimate,
Debug mode,
Win32 app,
Windows 7 x64 Home Premium.






TWell

  • Member
  • ****
  • Posts: 704
Re: Visual Studio C++: inline assembly to C++
« Reply #9 on: March 22, 2017, 01:18:41 AM »
So it is a WOW64 problem, gSharedInfo is 64-bit version in 32bit program too?
That aheList is 0 as pointers truncated.

if gSharedInfo use something like this, offset are more correct and HeEntrySize is 18h/24
Code: [Select]
typedef struct _SHAREDINFO64 {
    ULONGLONG psi;
    ULONGLONG aheList;
    ULONG HeEntrySize;
// ...
} SHAREDINFO64, *PSHAREDINFO64;
EDIT:
In main program something like this:
Code: [Select]
if (pSharedInfo->HeEntrySize == sizeof(HANDLEENTRY)) {// native
    EnumHandles(pSharedInfo);
} else { // in WOW64
    EnumHandles3264(pSharedInfo);
}
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int printf(const char * restrict format, ...);

typedef struct _HANDLEENTRY64 {
ULONGLONG pHead;
ULONGLONG pOwner;
BYTE bType;
BYTE bFlags;
WORD wUniq;
} HANDLEENTRY64, *PHANDLEENTRY64;

typedef struct _SHAREDINFO64 {
    ULONGLONG psi;
    ULONGLONG aheList;
    ULONG HeEntrySize;
    ULONGLONG pDispInfo;
    ULONG_PTR ulSharedDelta;
    ULONG_PTR awmControl;
    ULONG_PTR DefWindowMsgs;
    ULONG_PTR DefWindowSpecMsgs;
} SHAREDINFO64, *PSHAREDINFO64;

typedef struct _HOOK
{
ULONGLONG Handle;
ULONG LockObj;
ULONGLONG ThreadInfo;
ULONGLONG Desktop1;
ULONGLONG Self;
ULONGLONG NextHook;
LONG HookType;
ULONGLONG FunctionAddress;
ULONG Flags;
ULONG ModuleHandle;
PVOID Hooked;
PVOID Desktop2;
} HOOK,*PHOOK,**PPHOOK;
#define TYPE_HOOK 5

void EnumHandles3264(SHAREDINFO64 *pSharedInfo64)
{
struct _TEB* pTeb = NtCurrentTeb();
ULONGLONG offset = *(ULONGLONG*)(((BYTE*)pTeb)-0x2000+0x800+0x28); // pTeb->Win32ClientInfo.ulClientDelta
ULONG cHandleEntries = *((ULONG *) ((ULONG)pSharedInfo64->psi + 8));
HANDLEENTRY64 *Handle = (HANDLEENTRY64*)pSharedInfo64->aheList;
for(ULONG i = 0; i < cHandleEntries; ++i)
{
HANDLEENTRY64* pHandle = Handle++;
if(pHandle->bType != TYPE_HOOK) continue;
HOOK* HookInfo = (HOOK*)((UINT_PTR)pHandle->pHead - offset);
if(HookInfo)
{
printf("Found hook at %p", HookInfo);
printf(" Handle: %08llX %2d %d\n", HookInfo->Handle, HookInfo->HookType, HookInfo->Flags);
}
}
}
native EnumHandles()
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int printf(const char * restrict format, ...);

typedef struct _HOOK
{
HANDLE Handle;
ULONG LockObj;
PVOID ThreadInfo;
PVOID Desktop1;
PVOID Self;
PVOID NextHook;
LONG HookType;
PVOID FunctionAddress;
ULONG Flags;
ULONG ModuleHandle;
PVOID Hooked;
PVOID Desktop2;
ULONG bitField;
} HOOK, *PHOOK, **PPHOOK;
#define TYPE_HOOK 5

typedef struct _HANDLEENTRY {
PVOID pHead;
PVOID pOwner;
BYTE bType;
BYTE bFlags;
WORD wUniq;
} HANDLEENTRY, *PHANDLEENTRY;

typedef struct _SERVERINFO {
WORD   wRIPFlags;
WORD   wSRVIFlags;
WORD   wRIPPID;
WORD   wRIPError;
ULONG  cHandleEntries;
// incomplete
} SERVERINFO, *PSERVERINFO;

typedef struct _SHAREDINFO {
PSERVERINFO psi;
PHANDLEENTRY aheList;
ULONG HeEntrySize;
ULONG_PTR pDispInfo;
ULONG_PTR ulSharedDelta;
ULONG_PTR awmControl;
ULONG_PTR DefWindowMsgs;
ULONG_PTR DefWindowSpecMsgs;
} SHAREDINFO, *PSHAREDINFO;

void EnumHandles(SHAREDINFO *pSharedInfo)
{
struct _TEB* pTeb = NtCurrentTeb();
#ifdef _WIN64
ULONGLONG offset = *(ULONGLONG*)(((BYTE*)pTeb)+0x800+0x28); // pTeb->Win32ClientInfo.ulClientDelta
#else
ULONG offset = *(ULONG*)(((BYTE*)pTeb)+0x6CC+0x1C); // pTeb->Win32ClientInfo.ulClientDelta
#endif
ULONG cHandleEntries = pSharedInfo->psi->cHandleEntries;
HANDLEENTRY *Handle = (HANDLEENTRY*)pSharedInfo->aheList;
for(ULONG i = 0; i < cHandleEntries; ++i)
{
HANDLEENTRY* pHandle = Handle++;
if(pHandle->bType != TYPE_HOOK) continue;
HOOK* HookInfo = (HOOK*)((UINT_PTR)pHandle->pHead - offset);
if(HookInfo)
{
printf("Found hook at %p", HookInfo);
printf(" Handle: %08llX %2d %d\n", HookInfo->Handle, HookInfo->HookType, HookInfo->Flags);
}
}
}
« Last Edit: March 26, 2017, 12:17:29 AM by TWell »
-- Tim, not a assembler programmer

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #10 on: March 22, 2017, 01:54:49 AM »
@TWell,

i have a new code ( based in this link:  http://www.netfairy.net/?post=238 ), and this trouble was solved :eusa_dance:.

Now i'm trying print the Handle of hook, but i getting a Access Violation :icon_confused:.

TEB struct still is the same got of this link: http://b4you.net/blog/tag/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D?page=2/RK=0/RS=OnSynb5PqLHcGlxDbsJRgEqfmuM-

See:

Code: [Select]
typedef struct _HANDLEENTRY {
PVOID   phead;
PVOID   pOwner;
BYTE    bType;
BYTE    bFlags;
WORD    wUniq;
} HANDLEENTRY, *PHANDLEENTRY;

typedef struct _SERVERINFO {
WORD            wRIPFlags;
WORD            wSRVIFlags;
WORD            wRIPPID;
WORD            wRIPError;
ULONG           cHandleEntries;
} SERVERINFO, *PSERVERINFO;

typedef struct _SHAREDINFO {
PSERVERINFO  psi;
PHANDLEENTRY aheList;
ULONG   HeEntrySize;
} SHAREDINFO, *PSHAREDINFO;

typedef struct _PEB {
    BYTE Reserved1[2];
    BYTE BeingDebugged;
    BYTE Reserved2[229];
    PVOID Reserved3[59];
    ULONG SessionId;
} PEB, *PPEB;

typedef struct _CLIENT_ID
{
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef struct _TEB
{
    NT_TIB Tib;
    PVOID EnvironmentPointer;
    CLIENT_ID Cid;
    PVOID ActiveRpcInfo;
    PVOID ThreadLocalStoragePointer;
    PPEB Peb;
    ULONG LastErrorValue;
    ULONG CountOfOwnedCriticalSections;
    PVOID CsrClientThread;
    PVOID Win32ThreadInfo;
    ULONG Win32ClientInfo[0x1F];
    PVOID WOW32Reserved;
    ULONG CurrentLocale;
    ULONG FpSoftwareStatusRegister;
    PVOID SystemReserved1[0x36];
    PVOID Spare1;
    ULONG ExceptionCode;
    ULONG SpareBytes1[0x28];
    PVOID SystemReserved2[0xA];
    ULONG GdiRgn;
    ULONG GdiPen;
    ULONG GdiBrush;
    CLIENT_ID RealClientId;
    PVOID GdiCachedProcessHandle;
    ULONG GdiClientPID;
    ULONG GdiClientTID;
    PVOID GdiThreadLocaleInfo;
    PVOID UserReserved[5];
    PVOID GlDispatchTable[0x118];
    ULONG GlReserved1[0x1A];
    PVOID GlReserved2;
    PVOID GlSectionInfo;
    PVOID GlSection;
    PVOID GlTable;
    PVOID GlCurrentRC;
    PVOID GlContext;
    NTSTATUS LastStatusValue;
    UNICODE_STRING StaticUnicodeString;
    WCHAR StaticUnicodeBuffer[0x105];
    PVOID DeallocationStack;
    PVOID TlsSlots[0x40];
    LIST_ENTRY TlsLinks;
    PVOID Vdm;
    PVOID ReservedForNtRpc;
    PVOID DbgSsReserved[0x2];
    ULONG HardErrorDisabled;
    PVOID Instrumentation[0x10];
    PVOID WinSockData;
    ULONG GdiBatchCount;
    ULONG Spare2;
    ULONG Spare3;
    ULONG Spare4;
    PVOID ReservedForOle;
    ULONG WaitingOnLoaderLock;
    PVOID StackCommit;
    PVOID StackCommitMax;
    PVOID StackReserved;
} TEB, *PTEB;

int GetgSharedInfo()
{

PSHAREDINFO  gSharedInfo=NULL; 
HMODULE   huser32=NULL;
PHANDLEENTRY aheList=NULL;
ULONG_PTR pfnUserRegisterWowHandlers=NULL;
ULONG_PTR   k;

huser32=LoadLibrary(L"user32.dll");
if (huser32 == NULL)
{
printf("LoadLibrary faild\n");
return 0;
}
pfnUserRegisterWowHandlers = (ULONG_PTR)GetProcAddress(huser32, "UserRegisterWowHandlers");
if(pfnUserRegisterWowHandlers ==NULL)
{
printf("UserRegisterWowHandlers faild\n");
return 0;
}
gSharedInfo = (PSHAREDINFO)GetProcAddress(huser32, "gSharedInfo");
if( gSharedInfo != NULL )
{
printf("gSharedInfo=0x%x\n",gSharedInfo);
}
aheList = gSharedInfo->aheList; 
k = gSharedInfo->psi->cHandleEntries; 

PTEB pTeb = (PTEB)NtCurrentTeb();
UINT_PTR offset = pTeb->Win32ClientInfo[7];

for(ULONG i = 0; i < k; ++i)
{
HANDLEENTRY* pHandle = &aheList[i];
if(pHandle->bType != TYPE_HOOK) continue;
HOOK* HookInfo = (HOOK*)((PVOID*)pHandle->phead - offset);

if(HookInfo)
{
printf("Found hook at %p\n", HookInfo);
printf("Handle of hook is: %.8X",(HOOK*)HookInfo->Handle);
}
}

return 1;
}


adeyblue

  • Member
  • **
  • Posts: 85
    • Airesoft
Re: Visual Studio C++: inline assembly to C++
« Reply #11 on: March 22, 2017, 06:55:19 AM »
OK, see this is why you don't use undocumented stuff, because it changes. On 7x64 the proper offset is in slot 5 of Win32ClientInfo not 7. Also, that teb struct is 32-bit.

Code: [Select]
// other structs as necessary
typedef struct _HOOK
{
HANDLE Handle;
ULONG LockObj;
PVOID ThreadInfo;
PVOID Desktop1;
PVOID Self;
PVOID NextHook;
LONG HookType; // WH_ type
PVOID FunctionAddress;
ULONG Flags;
ULONG ModuleHandle;
PVOID Hooked;
PVOID Desktop2;
ULONG bitField;
} HOOK;

typedef struct _NeededTEB
{
BYTE unneeded[0x800];
UINT_PTR Win32ClientInfo[0x3e];
} NeededTEB;

#ifndef _WIN64
#error "64-bit only"
#endif

void EnumHooks()
{
HMODULE hMod = GetModuleHandleW(L"user32.dll");
SHARED_INFO* pSharedInf = (SHARED_INFO*)GetProcAddress(hMod, "gSharedInfo");
        if(!pSharedInfo) {printf("This isn't Win7 or above\n"); return;}
SIZE_T numHandles = pSharedInf->ServerInfo->numHandles;
NeededTEB* pTeb = (NeededTEB*)NtCurrentTeb();
UINT_PTR offset = pTeb->Win32ClientInfo[5];
printf("EnumHooks found %Iu handles, teb offset = %Ix\n", numHandles, offset);
for(SIZE_T i = 0; i < numHandles; ++i)
{
HANDLE_ENTRY* pEntry = &pSharedInf->HandleEntryList[i];
if(pEntry->Type == TYPE_HOOK)
{
HOOK* pHook = (HOOK*)(((UINT_PTR)pEntry->Head) - offset);
printf("Handle %Iu - Found hook at %p\nHandle = %p - Type = %d\n", i, pHook, pHook->Handle, pHook->HookType);
}
}
}

Code: [Select]
EnumHooks found 4778 handles, teb offset = fffff900c0010000
Handle 127 - Found hook at 00000000007F2AA0
Handle = 00000000000A007F - Type = -1
Handle 153 - Found hook at 0000000000801D50
Handle = 0000000000050099 - Type = 5
Handle 493 - Found hook at 0000000000813C50
Handle = 00000000005E01ED - Type = 2
Handle 635 - Found hook at 00000000009366D0
Handle = 000000000731027B - Type = 3
etc

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #12 on: March 22, 2017, 12:44:30 PM »
OK, see this is why you don't use undocumented stuff, because it changes. On 7x64 the proper offset is in slot 5 of Win32ClientInfo not 7. Also, that teb struct is 32-bit.

Code: [Select]
// other structs as necessary
typedef struct _HOOK
{
HANDLE Handle;
ULONG LockObj;
PVOID ThreadInfo;
PVOID Desktop1;
PVOID Self;
PVOID NextHook;
LONG HookType; // WH_ type
PVOID FunctionAddress;
ULONG Flags;
ULONG ModuleHandle;
PVOID Hooked;
PVOID Desktop2;
ULONG bitField;
} HOOK;

typedef struct _NeededTEB
{
BYTE unneeded[0x800];
UINT_PTR Win32ClientInfo[0x3e];
} NeededTEB;

#ifndef _WIN64
#error "64-bit only"
#endif

void EnumHooks()
{
HMODULE hMod = GetModuleHandleW(L"user32.dll");
SHARED_INFO* pSharedInf = (SHARED_INFO*)GetProcAddress(hMod, "gSharedInfo");
        if(!pSharedInfo) {printf("This isn't Win7 or above\n"); return;}
SIZE_T numHandles = pSharedInf->ServerInfo->numHandles;
NeededTEB* pTeb = (NeededTEB*)NtCurrentTeb();
UINT_PTR offset = pTeb->Win32ClientInfo[5];
printf("EnumHooks found %Iu handles, teb offset = %Ix\n", numHandles, offset);
for(SIZE_T i = 0; i < numHandles; ++i)
{
HANDLE_ENTRY* pEntry = &pSharedInf->HandleEntryList[i];
if(pEntry->Type == TYPE_HOOK)
{
HOOK* pHook = (HOOK*)(((UINT_PTR)pEntry->Head) - offset);
printf("Handle %Iu - Found hook at %p\nHandle = %p - Type = %d\n", i, pHook, pHook->Handle, pHook->HookType);
}
}
}

Code: [Select]
EnumHooks found 4778 handles, teb offset = fffff900c0010000
Handle 127 - Found hook at 00000000007F2AA0
Handle = 00000000000A007F - Type = -1
Handle 153 - Found hook at 0000000000801D50
Handle = 0000000000050099 - Type = 5
Handle 493 - Found hook at 0000000000813C50
Handle = 00000000005E01ED - Type = 2
Handle 635 - Found hook at 00000000009366D0
Handle = 000000000731027B - Type = 3
etc

@AdeyBlue,

thank very much, now your code works (building as x64 app).
You have a 32 bit version of this code?
the first code that i posted works fine only until Windows 8 32 bit  :(

« Last Edit: March 24, 2017, 01:30:07 PM by flashcoder »

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #13 on: March 23, 2017, 04:11:36 AM »
@AdeyBlue,

thank very much, now your code works (building as x64 app).
You have a 32 bit version of this code?
the first code that i posted works fine only until Windows 8 32 bit  :(
« Last Edit: March 24, 2017, 01:30:29 PM by flashcoder »

flashcoder

  • Regular Member
  • *
  • Posts: 20
Re: Visual Studio C++: inline assembly to C++
« Reply #14 on: March 23, 2017, 10:14:49 AM »
@TWell,

i tested your code and also works :t (except the 32-bit part).
« Last Edit: March 24, 2017, 05:27:38 AM by flashcoder »