Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Wednesday, September 28, 2011

A c++ class of Print wrong when program breakdown

Author:hying
A c++ class of Print wrong when program breakdown, Use it can to find reason of wrong and place of wrong.
Example:
----------------------------------------------------------------------------
System details:
-----------
Operating System:      Microsoft Windows XP Professional (Version 5.1, Build 2600)
CPU Information: Type: Intel Pentium compatible, Number Of Processors: 2, Architecture: Intel, Level: Unknown 15, Stepping: 10-25
Memory Information:    Memory Used 72%, Total Physical Memory 1048048KB, Physical Memory Available 286664KB, Total Virtual Memory 2097024KB, Available Virtual Memory 2054620KB, Working Set Min: 200KB Max: 1380KB .

Process details:
-----------
Thread number:1, Handle number:22
Use memory(K):3540, Use memory peak(K):3540, Page buffer pool(K):20, Page buffer pool(K):20, Non Page buffer pool peak(K):2
Page buffer pool peak(K):2, Virtual memory(K):3052, Virtual memory peak(K):3052, Page wrong:883

Exception details:
-----------
FirstChance:00000001, ExceptionCode:C0000005, ExceptionFlags:00000000, ExceptionAddress:004014B9
ExceptRem: STATUS_ACCESS_VIOLATION
Module: G:\testdump1.exe, Section: 01, Offset: 000004B9

Context details:
-----------
EFlags:00010206
EIP:004014B9
Ebp:0012FEF4
Esp:0012FEDC
Edi:00000000
Esi:0041A028
Ebx:7FFDE000
Edx:00000000
Ecx:00000009
Eax:00000009

Call stack:
-----------
Address   Frame     Function   SourceFile
004014B9  0012FEF4  testexp1+49  testdump1.cpp line 37
  Parameter struct TestClass* _pclass = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
  Parameter int* _pint = [0x00000000]
  Parameter int _int = 79
  Local double t_double = 79.000000
  Local char* t_pchar = "787878789"
  Local int** t_ppint = [0x0012FF00]
  Local enum TEnum t_Enum = 2
  Local int t_Tmpint2 = 9

00401516  0012FF8C  main+56  testdump1.cpp line 53
  Parameter int argc = 1
  Parameter char** argv = [0x00F4A680]
  Local int t_int = 78
  Local int* t_pint = [0x00000000]
  Local struct TestClass t_class = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
  Local char[60] command = ""

00414D83  0012FFB8  __startup+16F

Assembler Information:
-----------
testdump1.cpp
-------Line 25---------
00401470  push    ebp
00401471  mov     ebp, esp
00401473  add     esp, -18
-------Line 27---------
00401476  mov     dword ptr [ebp-4], 2
-------Line 29---------
0040147D  mov     eax, [ebp+8]
00401480  mov     edx, [ebp-4]
00401483  mov     [eax+4], edx
-------Line 31---------
00401486  lea     ecx, [ebp+C]
00401489  mov     [ebp-8], ecx
-------Line 32---------
0040148C  mov     dword ptr [ebp-C], 41A0C0
-------Line 33---------
00401493  fild    dword ptr [41A0B8]
00401499  fstp    qword ptr [ebp-14]
-------Line 34---------
0040149C  fld     qword ptr [ebp-14]
0040149F  call    00411FD0
004014A4  mov     [ebp+10], eax
-------Line 36---------
004014A7  push    dword ptr [ebp-C]
004014AA  call    0040C740
004014AF  pop     ecx
004014B0  mov     [ebp-18], eax
-------Line 37---------
004014B3  mov     edx, [ebp+C]
004014B6  mov     ecx, [ebp-18]
004014B9  mov     [edx], ecx  ; <-- EXCEPTION
-------Line 39---------
004014BB  mov     esp, ebp
004014BD  pop     ebp
004014BE  retn
------------------------Havs exception-----------------------------
int g_int = 0;
struct TestBaseClass
{
public:
  char Memchar;
};
struct TestClass: public TestBaseClass
{
public:
    int Mem1;
    int Mem2;
  TestClass* Mem3;
};
enum TEnum
{
  EnumIdx1 = 1,
  EnumIdx2 = 2,
};
void testexp1(TestClass* _pclass, int* _pint, int _int)
{
  TEnum t_Enum = EnumIdx2;
  {
    _pclass->Mem1 = t_Enum;
  }
  int** t_ppint = &_pint;
  char* t_pchar = "787878789";
  double t_double = g_int;
  _int = t_double;
  {
    int t_Tmpint2 = strlen(t_pchar);
    *_pint = t_Tmpint2;
  }
}
int _tmain(int argc, _TCHAR* argv[])
{
    char command[60];
    gets(command);
    TestClass t_class;
    t_class.Mem1 = 7;
    t_class.Mem2 = 8;
    t_class.Mem3 = NULL;
    int* t_pint = NULL;
    int t_int = 78;
  g_int = 79;
    __try
    {
        testexp1(&t_class, t_pint, t_int);
    }
    __except(1)
    {
        t_int++;
    }
    return 0;
}
----------------------------------------------------------------------------------------

How use:Need write oneself SetUnhandledExceptionFilter code on program. Then use the class.Hold out symbol table of MS PDB. Symbol table file place to the same of exe directory.

 Minidump.rar

Tuesday, September 27, 2011

Right use CPUID

Author:DiYhAcK

If want program of use cpuid command to be passed :

1.Judge SPU that whether hold out cpuid command
The way: 21st of eflags(ID) whether can change


Code:
BOOL __declspec(naked) IsCpuidValid()
{
  __asm
  {
    pushfd
    pop eax             //eax = eflags
    mov ebx, eax
    xor eax, 00200000h  //toggle bit 21, eflags.[ID]
    push eax
    popfd
    pushfd
    pop eax
    cmp eax, ebx
    jz NO_CPUID
    mov eax, 1
    ret
NO_CPUID:
    xor eax, eax
    ret
  }
}
2.If cpu hold out cpuid command, First judge whether hold out function num before use such cpuid function num.


Code:
    CPUID_ARGS ca;
    ca.eax = 0;
    cpuid32(&ca);
    char Vendor[13];
    *((PULONG)&Vendor[0]) = ca.ebx;
    *((PULONG)&Vendor[4]) = ca.edx;
    *((PULONG)&Vendor[8]) = ca.ecx;
    Vendor[12] = '\0';

    printf("CPU Vendor: %s\n", Vendor);
    printf("Max Standard function: 0x%08x\n", ca.eax);

    ca.eax = 0x80000000;
    cpuid32(&ca);

    printf("Max Extended function: 0x%08x\n", ca.eax);
3.Reference appropriate help standard of CPU manufacturer to use homologous function num

Code:
if(strcmp(Vendor, "GenuineIntel") == 0)
{
    //Reference IPM-241618
    if(ca.eax >= 0x80000004) //support brand string
    {
        char Brand[48];
        ca.eax = 0x80000002;
        cpuid32(&ca);
        *((PULONG)&Brand[0]) = ca.eax;
        *((PULONG)&Brand[4]) = ca.ebx;
        *((PULONG)&Brand[8]) = ca.ecx;
        *((PULONG)&Brand[12]) = ca.edx;

        ca.eax = 0x80000003;
        cpuid32(&ca);
        *((PULONG)&Brand[16]) = ca.eax;
        *((PULONG)&Brand[20]) = ca.ebx;
        *((PULONG)&Brand[24]) = ca.ecx;
        *((PULONG)&Brand[28]) = ca.edx;

        ca.eax = 0x80000004;
        cpuid32(&ca);
        *((PULONG)&Brand[32]) = ca.eax;
        *((PULONG)&Brand[36]) = ca.ebx;
        *((PULONG)&Brand[40]) = ca.ecx;
        *((PULONG)&Brand[44]) = ca.edx;

        printf("Brand: %s\n", Brand);
    }
}
else if(strcmp(Vendor, "AuthenticAMD") == 0)
{
    //Reference APM-25481
    if(ca.eax >= 0x80000004) //support brand string
    {
        char Brand[48];
        ca.eax = 0x80000002;
        cpuid32(&ca);
        *((PULONG)&Brand[0]) = ca.eax;
        *((PULONG)&Brand[4]) = ca.ebx;
        *((PULONG)&Brand[8]) = ca.ecx;
        *((PULONG)&Brand[12]) = ca.edx;

        ca.eax = 0x80000003;
        cpuid32(&ca);
        *((PULONG)&Brand[16]) = ca.eax;
        *((PULONG)&Brand[20]) = ca.ebx;
        *((PULONG)&Brand[24]) = ca.ecx;
        *((PULONG)&Brand[28]) = ca.edx;

        ca.eax = 0x80000004;
        cpuid32(&ca);
        *((PULONG)&Brand[32]) = ca.eax;
        *((PULONG)&Brand[36]) = ca.ebx;
        *((PULONG)&Brand[40]) = ca.ecx;
        *((PULONG)&Brand[44]) = ca.edx;

        printf("Brand: %s\n", Brand);
    }
}
else //if(...)
{
    //Reference help of other CPU manufacturer
}

Friday, September 23, 2011

Get OpCode's size of function

Author:GStar
Main idea: Analyse jmp jcc etc. jump type command, That need find farthest address of command; Find ret command; If current command is ret and fartherst address of command, Function is End.

Code:
GetProcSize  proc  uses esi ebx edi pProc:DWORD
;eax    command length
;ebx    current command
;ecx    function addr
;esi    Current command address, and That is farthest address of command

  mov    esi,pProc
  mov   edi,esi
 
  invoke  GetCodeSize,esi
  .while  eax
    .if  eax == 2 && ( (byte ptr[esi] > 70H && byte ptr[esi] < 7FH) || byte ptr[esi] == 0EBH )
      movsx  ebx,byte ptr[esi+1]
    .elseif  eax == 5 && byte ptr[esi] == 0E9H
      mov   ebx,[esi+1]
    .elseif eax == 6 && byte ptr[esi] == 0FH && byte ptr[esi+1] > 80H && byte ptr[esi+1] < 8FH
      mov   ebx,[esi+2]
    .else
      .if  (byte ptr[esi] == 0C2H || byte ptr[esi] == 0C3H || byte ptr[esi] == 0CAH || byte ptr[esi] == 0CBH) && esi == edi
        lea   eax,[esi+eax]
        sub    eax,pProc
        ret
      .else
        xor    ebx,ebx
      .endif
    .endif
    add    esi,eax
    test  ebx,ebx
    .if  !sign?
      add   ebx,esi
      .if  ebx > edi
        mov   edi,ebx
      .endif
    .endif
    .if  esi > edi
      mov   edi,esi
    .endif
    invoke  GetCodeSize,esi
  .endw
  xor    eax,eax
  ret
GetProcSize endp

Remark:
1、GetCodeSize is lde32 disassembling engine.
2、The code has limtations, Cant's analysis jmp [xx] command;By behind jmp to ret command's function may be get full size. But can almost analyse by compiler generated.

Wednesday, September 21, 2011

Code for get hard disk ID/network card MAC

Author:AZMC
Be free and at leisure, Neaten code for hard disk ID/network card MAC.


Code:
// =============================================================================
// xID.h - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#pragma once

#ifndef _X_ID_
#define _X_ID_

typedef struct _IDSECTOR {
  USHORT  wGenConfig;
  USHORT  wNumCyls;
  USHORT  wReserved;
  USHORT  wNumHeads;
  USHORT  wBytesPerTrack;
  USHORT  wBytesPerSector;
  USHORT  wSectorsPerTrack;
  USHORT  wVendorUnique[3];
  CHAR  sSerialNumber[20];
  USHORT  wBufferType;
  USHORT  wBufferSize;
  USHORT  wECCSize;
  CHAR  sFirmwareRev[8];
  CHAR  sModelNumber[40];
  USHORT  wMoreVendorUnique;
  USHORT  wDoubleWordIO;
  USHORT  wCapabilities;
  USHORT  wReserved1;
  USHORT  wPIOTiming;
  USHORT  wDMATiming;
  USHORT  wBS;
  USHORT  wNumCurrentCyls;
  USHORT  wNumCurrentHeads;
  USHORT  wNumCurrentSectorsPerTrack;
  ULONG  ulCurrentSectorCapacity;
  USHORT  wMultSectorStuff;
  ULONG  ulTotalAddressableSectors;
  USHORT  wSingleWordDMA;
  USHORT  wMultiWordDMA;
  BYTE  bReserved[128];
} IDSECTOR, *PIDSECTOR;

extern char xID[ 64 ];

void xGetHardDiskID();
void xGetNetCardID();

#endif

// =============================================================================
// xID.cpp - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#include "stdafx.h"

#include "xID.h"

#include <winioctl.h>

char xID[ 64 ] = { 0 };

void xGetHardDiskID()
{
  HANDLE hDevice;
  BOOL bResult;
  DWORD dwRet;

  memset( ( void* )xID,0,64 );

  hDevice = CreateFile( "\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL  );
  if( hDevice == INVALID_HANDLE_VALUE ) return;

  GETVERSIONINPARAMS vip;
  bResult = DeviceIoControl( hDevice,SMART_GET_VERSION,NULL,0,&vip,sizeof( GETVERSIONINPARAMS ),&dwRet,NULL );
  if( !bResult ) {
    CloseHandle( hDevice );
    return;
  }
  if( vip.bIDEDeviceMap == 0 ) {
    CloseHandle( hDevice );
    return;
  }

  SENDCMDINPARAMS cmdin;
  memset( ( void* )&cmdin,0,sizeof( cmdin ) );
  cmdin.irDriveRegs.bSectorCountReg = 0x01;
  cmdin.irDriveRegs.bSectorNumberReg = 0x01;
  cmdin.irDriveRegs.bFeaturesReg = 0x00;
  cmdin.bDriveNumber = 0x00;
  cmdin.irDriveRegs.bCylLowReg = 0x00;
  cmdin.irDriveRegs.bCylHighReg = 0x00;
  cmdin.irDriveRegs.bDriveHeadReg = 0xa0;
  cmdin.irDriveRegs.bCommandReg = 0xec;
  cmdin.cBufferSize = 0x200;

  BYTE cmdout[ sizeof( SENDCMDOUTPARAMS ) + 512 -1 ];
  memset( ( void* )cmdout,0,sizeof( SENDCMDOUTPARAMS ) + 512 -1 );
  SENDCMDOUTPARAMS* pcmdout = ( SENDCMDOUTPARAMS* )&cmdout;
  pcmdout->cBufferSize = 0x200;

  bResult = DeviceIoControl(  hDevice,SMART_RCV_DRIVE_DATA,( LPVOID )&cmdin,sizeof( SENDCMDINPARAMS ),cmdout,sizeof( cmdout ),&dwRet,NULL );
  if( !bResult ) {
    CloseHandle( hDevice );
    return;
  }

  IDSECTOR* pisd = ( IDSECTOR* )&cmdout[ sizeof( SENDCMDOUTPARAMS ) - 1 ];

  char tmpch1,tmpch2;
  int j = 0;
  for( int i = 0; i < sizeof( pisd->sSerialNumber ); i += 2 ) {
    tmpch1 = pisd->sSerialNumber[ i + 1 ];
    tmpch2 = pisd->sSerialNumber[ i  ];
    if( isdigit( tmpch1 ) || isalpha( tmpch1 ) ) {
      xID[ j++ ] = tmpch1;
    }
    if( isdigit( tmpch2 ) || isalpha( tmpch2 ) ) {
      xID[ j++ ] = tmpch2;
    }
  }

  CloseHandle( hDevice );
}

#include <Iphlpapi.h.>
#pragma comment( lib,"Iphlpapi.lib" )

void xGetNetCardID()
{
  PIP_ADAPTER_INFO pinfo;
  unsigned char buf[ 4096 ];
  unsigned long len = 4096;
  unsigned long nError = 0;

  ZeroMemory( buf,4096 );
  pinfo = ( PIP_ADAPTER_INFO )buf;

  nError = GetAdaptersInfo( pinfo,&len );
  if( nError == ERROR_SUCCESS ) {
    sprintf( xID,"%02X%02X%02X%02X%02X%02X",pinfo->Address[0],pinfo->Address[1],pinfo->Address[2],pinfo->Address[3],pinfo->Address[4],pinfo->Address[5] );
  }
}

===〉调用相应的函数,ID 保存在 xID 数组中。
===〉一般地,要从 PhysicalDrive0/PhysicalDrive1/PhysicalDrive2/PhysicalDrive3 循环获取。
===〉以下为 VBScript 代码

strComputer = "."  'Dot (.) equals local computer in WMI

Set objWMIService = GetObject("winmgmts:\\" & strComputer)
Set colServices = objWMIService.InstancesOf("Win32_PhysicalMedia")

For Each objService In colServices
    WScript.Echo "Win32_PhysicalMedia--Tag         :" & objService.Tag & vbCrLf & _
                 "                   --SerialNumber:" & Trim(objService.SerialNumber) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_Processor")

For Each objService In colServices
    WScript.Echo "Win32_Processor--ProcessorId:" & objService.ProcessorId & vbCrLf & _
                 "               --UniqueId   :" & Trim(objService.UniqueId) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_NetworkAdapter")

For Each objService In colServices
    WScript.Echo "Win32_NetworkAdapter--MACAddress:" & objService.MACAddress & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BIOS")

For Each objService In colServices
    WScript.Echo "Win32_BIOS--SerialNumber :" & objService.SerialNumber & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BaseBoard")

For Each objService In colServices
    WScript.Echo "Win32_BaseBoard--Tag          :" & objService.Tag & vbCrLf & _
                 "               --SerialNumber :" & objService.SerialNumber & vbCrLf
Next

Sunday, August 7, 2011

FSD inline hook

Anthor:hfyy
Time:2008-05-13 19:32:44

This is unfinished code,I wanted to hide file,But The code turn up question to worte specific for hide file.So Pubilish to help,


code:
#include "ntddk.h"

typedef BOOLEAN BOOL;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned long ULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;

typedef struct _FILE_BOTH_DIR_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    CCHAR ShortNameLength;
    WCHAR ShortName[12];
    WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

typedef struct tag_QUERY_DIRECTORY
{
  ULONG Length;
  PUNICODE_STRING FileName;
  FILE_INFORMATION_CLASS FileInformationClass;
  ULONG FileIndex;
} QUERY_DIRECTORY, *PQUERY_DIRECTORY;

typedef struct  _REQINFO{
  PIO_COMPLETION_ROUTINE    OldCompletion;
} REQINFO,*PREQINFO;

NTSYSAPI NTSTATUS
ObReferenceObjectByName(
            IN PUNICODE_STRING ObjectPath,
            IN ULONG Attributes,
            IN PACCESS_STATE PassedAccessState OPTIONAL,
            IN ACCESS_MASK DesiredAccess OPTIONAL,
            IN POBJECT_TYPE ObjectType,
            IN KPROCESSOR_MODE AccessMode,
            IN OUT PVOID ParseContext OPTIONAL,
            OUT PVOID *ObjectPtr);

typedef  NTSTATUS  (*OLDIRPMJDIRECTORYCONTROL)(IN PDEVICE_OBJECT,IN PIRP);



NTSTATUS HookFastFat();//hook fastfat.sys
NTSTATUS MyCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context);//完成示例
VOID write();//写入补丁
VOID write_back();//写回补丁
NTAPI MyDirectoryControl();//这个函数将inline在IRP_MJ_DIRECTORY_CONTROL之前
NTSTATUS Check();//测试一下  其实是硬编码 如果想应用在不同平台 需要改进


PDRIVER_OBJECT  pFile=NULL;//fastfat的PDRIVER_OBJECT
OLDIRPMJDIRECTORYCONTROL  OldIrpMjDirectoryControl;//原来的MajorFunction[IRP_MJ_DIRECTORY_CONTROL]
BOOL hook;//hook标志
PIO_STACK_LOCATION  irpStack;
DWORD        context;//这个用来传递完成示例的地址

// This is our unload function

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )

{

    DbgPrint("OnUnload called\n");
  if (hook)
  {
    write_back();
  }
  //这里我用的方法是inline hook 还可以用下面方法hook IRP
  /*if (OldIrpMjDirectoryControl&&pFile)
  {
    InterlockedExchange((PLONG)&pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL],(LONG)OldIrpMjDirectoryControl);
  }*/

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,

                     IN PUNICODE_STRING theRegistryPath)

{
    NTSTATUS ntStatus;
    DbgPrint("I loaded!");
    ntStatus=HookFastFat();
    if(!NT_SUCCESS(ntStatus))
      return  ntStatus;
      // Initialize the pointer to the unload function

      // in the DriverObject

    theDriverObject->DriverUnload  = OnUnload;

    return STATUS_SUCCESS;

}
//hook fastfat.sys
NTSTATUS HookFastFat()
{
  char *p;
  int  i;
  NTSTATUS ntStatus;
  UNICODE_STRING  sFastFat;
  WCHAR  FastFatBuffer[]=L"\\FileSystem\\Fastfat";
  RtlInitUnicodeString(&sFastFat,FastFatBuffer);
  //得到pFile
  ntStatus=ObReferenceObjectByName(&sFastFat,
                  OBJ_CASE_INSENSITIVE,NULL,0,
                  ( POBJECT_TYPE )IoDriverObjectType,
                  KernelMode,NULL,&pFile);
 
  if(!NT_SUCCESS(ntStatus))
    return ntStatus;
  //保持一下旧的MajorFunction[IRP_MJ_DIRECTORY_CONTROL]
  OldIrpMjDirectoryControl=pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL];
  p=(char *)OldIrpMjDirectoryControl;
  //函数地址change hook
  /*if (OldIrpMjDirectoryControl)
  {
    InterlockedExchange((PLONG)&pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL],(LONG)MyControl);
  }*/
  //DbgPrint("%08X",p);
  /*for(i=0;i<7;i++)
  {
    DbgPrint("-0x%02X",(unsigned char)p[i]);
  }*/
  //在此处将补丁写入 将hook标志置TRUE
  if(NT_SUCCESS(Check()))
  {
    DbgPrint(" check SUCCESS");
    write();
    hook=TRUE;
  }
  else
    DbgPrint(" check UNSUCCESSFUL");
  return  ntStatus;
}
//测试一下
NTSTATUS Check()
{
  int i=0;
  char *p=(char *)OldIrpMjDirectoryControl;
  char c[]={0x6a,0x18,0x68,0x20,0x3d,0xd8,0xf9};
  for(;i<7;i++)
  {
    DbgPrint("-0x%02X",(unsigned char)p[i]);
    if(p[i]!=c[i])
    {
      return STATUS_UNSUCCESSFUL;
    }
  }
  return STATUS_SUCCESS;
}

//写入补丁
VOID write()
{
  KIRQL oldIrql;
  char *actual_function=(char *)OldIrpMjDirectoryControl;
  char *non_paged_memory;
  unsigned long detour_address;
  unsigned long reentry_address;
  int i = 0;
  //jmp 11223344
  char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00 };
  //要返回的地址是原来地址+7
  reentry_address = ((unsigned long)OldIrpMjDirectoryControl) + 7;
  //分配空间 要是NonPagedPool
  non_paged_memory = ExAllocatePool(NonPagedPool,1024);
  //将补丁写入non_paged_memory
  for(i=0;i<1024;i++)
  {
    ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)MyDirectoryControl)[i];
  }
  //将地址保持在detour_address
  detour_address = (unsigned long)non_paged_memory;
  //将11223344替换为真正补丁地址
  *( (unsigned long *)(&newcode[1]) ) = detour_address;

  //将AAAAAAAA替换为真正的返回地址
  for(i=0;i<1024;i++)
  {
    if( (0xAA == ((unsigned char *)non_paged_memory)[i]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+1]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+2]) &&
      (0xAA == ((unsigned char *)non_paged_memory)[i+3]))
    {
      // we found the address 0xAAAAAAAA
      // stamp it w/ the correct address
      *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address;
      break;
    }
  }
  oldIrql = KeRaiseIrqlToDpcLevel();
  //写入补丁了
  __asm
  {
            push eax
            mov  eax, CR0
            and  eax, 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }

  for(i=0;i < 7;i++)
  {
    actual_function[i] = newcode[i];
  }

  __asm
    {
            push eax
            mov  eax, CR0
            or   eax, NOT 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }
  KeLowerIrql(oldIrql);
}
//写回
VOID write_back()
{
  KIRQL oldIrql;
  char *actual_function=(char *)OldIrpMjDirectoryControl;
  //将原来的指令写回 此处用的硬编码
  char c[]={0x6a,0x18,0x68,0x20,0x3d,0xd8,0xf9};
  int i;
  oldIrql = KeRaiseIrqlToDpcLevel();
  __asm
  {
            push eax
            mov  eax, CR0
            and  eax, 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
    }

  for(i=0;i < 7;i++)
  {
    actual_function[i] = c[i];
  }

  __asm
    {
            push eax
            mov  eax, CR0
            or   eax, NOT 0FFFEFFFFh
            mov  CR0, eax
            pop  eax
  }
  KeLowerIrql(oldIrql);
}
//此处为naked 函数 防止编译器放入额外操作码
__declspec(naked) NTAPI MyDirectoryControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
  __asm
  {   
      pushad
      pushfd
  }
  //此处设置IRP CompletionRoutine并将原来的CompletionRoutine地址保存放入context
  irpStack=IoGetCurrentIrpStackLocation(Irp);
  irpStack->Control = 0;
  irpStack->Control |= SL_INVOKE_ON_SUCCESS;
  irpStack->Context=(PIO_COMPLETION_ROUTINE)ExAllocatePool(NonPagedPool,sizeof(PREQINFO));
  ((PREQINFO)irpStack->Context)->OldCompletion=irpStack->CompletionRoutine;
  irpStack->CompletionRoutine=(PIO_COMPLETION_ROUTINE)MyCompletionRoutine;
  __asm
  {   
      popfd
      popad
  }
  __asm
  {   
    // exec missing instructions
    push  18h
    push    0F9D83D20h
  }
    // jump to re-entry location in hooked function
    // this gets 'stamped' with the correct address
    // at runtime.
    //
    // we need to hard-code a far jmp, but the assembler
    // that comes with the DDK will not poop this out
    // for us, so we code it manually
    // jmp FAR 0x08:0xAAAAAAAA
  __asm
  {
    _emit 0xEA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0x08
    _emit 0x00
  }
}
//CompletionRoutine
NTSTATUS MyCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context)
{
  PIO_COMPLETION_ROUTINE old;
  old=((PREQINFO)Context)->OldCompletion;
  DbgPrint("MyCompletionRoutine called");
  ExFreePool(Context);
  if ((Irp->StackCount>(ULONG)1)&&(old!=NULL))
  {
    return  (old)(DeviceObject,Irp,NULL);
  }
  else
    return  Irp->IoStatus.Status;
}

How to bypass message break

Anthor:RYYMike
Guess one:Through window subclass to operate
Checking:That is Impossible .Subclassing operation need to windows receive massage.To do so would still be broken,code of function also point to processing message code after broken,so no to bypass effect of message breaking.

Guess two:Through hooking to operate
Preliminary idea:First step use SetWindowsHookEx intercept and capture message first,After that,Intercept of Message dispense to original windows,Modified msg's parameter.

Question:How to realized message breaking of OLLDBG?If message breaking through to hooking created yet,Depending on specialty of hooking installation: 根据钩子的安装特点:First installation in the behind after the installation,in the front,So debugger's message breaking before execute hook function oneself be breaked yet.

Confirmation:Through create one windows oneself,According to the above hook and don't return breaking,That demonstrate message breaking not through created hooking to realize.
examples://C++
#include <windows.h>
  HWND HookHwnd;         //Hooked windows
  UINT HookMsg;          //sub-definite windows's msg
  int HookBool;          //Window is be created or be called
    WNDPROC HookProc;      //Old address
  HHOOK HookID;          //
    char StoreString[50];  //Return import string
LRESULT  CALLBACK AvoidProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam){//Escape hooked function
  if(lParam&0x80000000){//Enter one key generate two event:WM_KEYDOWN和WM_KEYUP,So removed one
    if(Msg== HookMsg){//
static int n;                                                   //
static char HideString[50];                          
HideString[n]='*';
StoreString[n]=wParam;
n=n+1;                                                        //
SetWindowText(hwnd,HideString);             //“*”
    return 1;                   
    }
  }
return CallWindowProc ((WNDPROC)HookProc,hwnd,Msg,wParam,lParam);//Call old window
 
}

LRESULT   CALLBACK MessageHook(int nCode,WPARAM wParam,LPARAM lParam){//Hooking callback function
    if (GetFocus()==HookHwnd){//判断输入焦点是不是想逃脱断点的窗口
        if (HookBool==1){
          static int Count;//判断是否已进行过GetWindowLong
          if (Count==0){
         HookProc=(WNDPROC)GetWindowLong(HookHwnd,GWL_WNDPROC);                                          //得到以前的窗口
   HookProc = (WNDPROC)SetWindowLong(HookHwnd, GWL_WNDPROC, (LONG)AvoidProc);//窗口子类化
          Count=1;
          }
          }
  PostMessage(HookHwnd,HookMsg,wParam,lParam);//传递消息
    }
return 1;
}

int MessageBreakAvoid(HWND hwnd,UINT msg,int Bool){//挂钩的函数,并进行一些初始化
  HookHwnd=hwnd;                         //初始化
  HookMsg=msg;   
    HookBool=Bool;
  HookID=SetWindowsHookEx(WH_KEYBOARD,MessageHook,GetModuleHandle(NULL),GetCurrentThreadId());//进行挂钩
return 0; 
}

int UnMessageBreakAvoid(){//删除钩子
  UnhookWindowsHookEx(HookID);
return 0; 
}
Next code followed by above code,example to do,

int PASCAL  WinMain(HINSTANCE MyHinst,HINSTANCE hPrev,LPSTR CmdLine,int ShowNumber){
HWND hwndB=CreateWindow("edit","个人简介",WS_VISIBLE,20,130,950,950,NULL,NULL,MyHinst,NULL);
ShowWindow(hwndB,1);
UpdateWindow(hwndB);
MSG MyMsg;
MessageBreakAvoid(hwndB,1101,1);                     ///注意这里
while (GetMessage(&MyMsg, NULL, 0, 0))
{
TranslateMessage(&MyMsg);
DispatchMessage(&MyMsg);
}
UnMessageBreakAvoid;
return TRUE;
}
The first step create window,after that,use MessageBreakAvoid to bypass message breaking,The second paramenter of MessageBreakAvoid convert WM_KEYDOWN or WM_KEYUP to custom message,There is 1101,When set this,You try large number,otherwise collide with windows msg code.
Th third paramenter is be create oneself or not

Debug return:succeed to bypass OllyDbg's msg trace.

Wednesday, August 3, 2011

Write a WPE

Author:taokla
I write tool of cut out packet and send packet at with WPE,Now I take out to share.
Download:http://filemarkets.com/file/newbing/b87f6040/

Tuesday, August 2, 2011

Programming of Asterisk Viewer

Author:qqaben
I download a software of Asterisk Viewer these two days,Software has ugly windows And farraginous performance,Let me not inthe mood to use, So I writed myself.I know to send WM_GETTEXT event for get window's text,do it:

code:
//控制台
    ..........
    while(1)
    {
      Sleep(1000);
      POINT Point;
      ::GetCursorPos(&Point);
      HWND m_hWnd=WindowFromPoint(Point);
      if(m_hWnd)
      {
        char szText[256];
        int iLength = SendMessage(m_hWnd,WM_GETTEXT,256,(LPARAM)szText);
        szText[iLength]='\0';
        {
          char szClassName[128];
          int iClassLength = GetClassName(m_hWnd,szClassName,128);
          szClassName[iClassLength] = '\0';
          printf("%s  ClassName:%s\n",szText,szClassName);
        }
      } 
    }
    .............
Watch the picture,We get right edit's text when moved to login(用户名),however,We can't get nothing on passwd edit.It seems some protection after edit seting up ES_PASSWD styles.Maybe don't use WM_GETTEXT,Wathch MSDN:

Displays an asterisk (*) for each character typed into the edit control. This style is valid only for singleline edit controls.

To change the characters that is displayed, or set or clear this style, use the EM_SETPASSWORDCHAR message.

Can I get passwd if password be sent EM_SETPASSWORDCHAR first,after be sent WM_GETTEXT ? Test it,I can't get yet.

Watch other people' software,OD loaded,bp GetWindowLong.

F9 run,Drag magnifier of soft,Stop there:

00401ABC  |> \6A F0         push    -10                           ; /Index = GWL_STYLE

  00401ABE  |.  FF75 10       push    dword ptr [ebp+10]            ; |hWnd
  00401AC1  |.  FF15 0C924000 call    dword ptr [<&USER32.GetWind>  ; \GetWindowLongA
  00401AC7  |.  8BD8          mov     ebx, eax
  00401AC9  |.  8D85 D8FCFFFF lea     eax, dword ptr [ebp-328]      ;  Stack Address =0012F87C, (ASCII "EDIT")
  00401ACF  |.  68 ECB14000   push    0040B1EC                      ;  ASCII "EDIT"
  00401AD4  |.  50            push    eax                           ;  可见在GetWindowLong前面已经调用过GetClassName
  00401AD5  |.  E8 361B0000   call    00403610                      ;  test window's type of magnifier and EDIT
  00401ADA  |.  59            pop     ecx
  00401ADB  |.  85C0          test    eax, eax
  00401ADD  |.  59            pop     ecx
  00401ADE  |.  0F84 CA000000 je      00401BAE                      ;   Edit, jump keyt
  ..........

  00401BAE  |> \F6C3 20       test    bl, 20
  00401BB1  |.  74 57         je      short 00401C0A
  00401BB3  |.  833D 4CE44000>cmp     dword ptr [40E44C], 0
  00401BBA  |.^ 74 D9         je      short 00401B95
  00401BBC  |.  8D45 14       lea     eax, dword ptr [ebp+14]
  00401BBF  |.  50            push    eax
  00401BC0  |.  FF75 10       push    dword ptr [ebp+10]            ;  可以用spy查看一下,此处存放的是密码框的句柄
  00401BC3  |.  FFD7          call    edi                           ;  USER32.GetWindowThreadProcessId
  00401BC5  |.  FF75 14       push    dword ptr [ebp+14]            ; /ProcessId
  00401BC8  |.  6A 00         push    0                             ; |Inheritable = FALSE
  00401BCA  |.  68 3A040000   push    43A                           ; |Access = CREATE_THREAD|VM_OPERATION|VM_READ|VM_WRITE|QUERY_INFORMATION
  00401BCF  |.  FF15 34904000 call    dword ptr [<&KERNEL32.OpenP>  ; \OpenProcess
  00401BD5  |.  8BF0          mov     esi, eax
  00401BD7  |.  85F6          test    esi, esi
  00401BD9  |.  74 1C         je      short 00401BF7
  00401BDB  |.  8D85 D8FEFFFF lea     eax, dword ptr [ebp-128]
  00401BE1  |.  50            push    eax
  00401BE2  |.  FF75 10       push    dword ptr [ebp+10]
  00401BE5  |.  56            push    esi
  00401BE6  |.  E8 01F6FFFF   call    004011EC                       ;  keyt
  00401BEB  |.  83C4 0C       add     esp, 0C
  00401BEE  |.  56            push    esi                            ; /hObject
  00401BEF  |.  FF15 38914000 call    dword ptr [<&KERNEL32.Close>   ; \CloseHandle
  00401BF5  |.  EB 13         jmp     short 00401C0A
  00401BF7  |>  8D85 D8FEFFFF lea     eax, dword ptr [ebp-128]
  00401BFD  |.  68 50E44000   push    0040E450
  00401C02  |.  50            push    eax
  00401C03  |.  E8 98130000   call    00402FA0
  00401C08  |.  59            pop     ecx
  00401C09  |.  59            pop     ecx
  00401C0A  |>  8D85 D8FEFFFF lea     eax, dword ptr [ebp-128]
  00401C10  |.  50            push    eax                            ; /Text
  00401C11  |.  68 EC030000   push    3EC                            ; |/ControlID = 3EC (1004.)
  00401C16  |.  FF75 08       push    dword ptr [ebp+8]              ; ||hWnd
  00401C19  |.  FF15 94914000 call    dword ptr [<&USER32.GetDlgI>   ; |\GetDlgItem
  00401C1F  |.  50            push    eax                            ; |hWnd
  00401C20  |.  FF15 10924000 call    dword ptr [<&USER32.SetWind>   ; \SetWindowTextA 

  run in call    004011EC

  004011EC  /$  6A 00         push    0
  004011EE  |.  FF7424 10     push    dword ptr [esp+10]
  004011F2  |.  FF7424 10     push    dword ptr [esp+10]           ;  Edit 的句柄, 就叫它 m_EditHwnd 吧
  004011F6  |.  FF7424 10     push    dword ptr [esp+10]           ;  调用OpenProcess后返回的进程句柄 ,先叫它 m_ThreadHandle
  004011FA  |.  E8 01FEFFFF   call    00401000                     ;  某个函数,形如:Function(var1,var2,var3,var4)
  004011FF  |.  83C4 10       add     esp, 10
  00401202  \.  C3            retn[/code] 
 再跟进call    00401000    
  00401000  /$  55            push    ebp
  00401001  |.  8BEC          mov     ebp, esp
  00401003  |.  6A FF         push    -1
  00401005  |.  68 38924000   push    00409238
  0040100A  |.  68 B0314000   push    004031B0                            ;  SE 处理程序安装
  0040100F  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
  00401015  |.  50            push    eax
  00401016  |.  64:8925 00000>mov     dword ptr fs:[0], esp
  0040101D  |.  81EC 30010000 sub     esp, 130
  00401023  |.  53            push    ebx
  00401024  |.  56            push    esi
  00401025  |.  57            push    edi
  00401026  |.  33F6          xor     esi, esi
  00401028  |.  8975 E4       mov     dword ptr [ebp-1C], esi
  0040102B  |.  8975 DC       mov     dword ptr [ebp-24], esi
  0040102E  |.  8975 D0       mov     dword ptr [ebp-30], esi
  00401031  |.  8975 E0       mov     dword ptr [ebp-20], esi
  00401034  |.  8975 FC       mov     dword ptr [ebp-4], esi
  00401037  |.  68 60B04000   push    0040B060                            ; /pModule = "user32"
  0040103C  |.  FF15 6C904000 call    dword ptr [<&KERNEL32.GetModuleHa>  ; \GetModuleHandleA
  00401042  |.  8945 CC       mov     dword ptr [ebp-34], eax
  00401045  |.  3BC6          cmp     eax, esi
  00401047  |.  0F84 17010000 je      00401164
  0040104D  |.  8B45 0C       mov     eax, dword ptr [ebp+C]
  00401050  |.  8985 C4FEFFFF mov     dword ptr [ebp-13C], eax
  00401056  |.  807D 14 00    cmp     byte ptr [ebp+14], 0
  0040105A  |.  B8 50B04000   mov     eax, 0040B050                       ;  ASCII "SendMessageW"
  0040105F  |.  75 05         jnz     short 00401066
  00401061  |.  B8 40B04000   mov     eax, 0040B040                       ;  ASCII "SendMessageA"
  00401066  |>  50            push    eax                                 ; /ProcNameOrOrdinal
  00401067  |.  FF75 CC       push    dword ptr [ebp-34]                  ; |hModule
  0040106A  |.  FF15 D8904000 call    dword ptr [<&KERNEL32.GetProcAddr>  ; \GetProcAddress
  00401070  |.  8985 C8FEFFFF mov     dword ptr [ebp-138], eax            ;  获取了SendMessage 函数的地址,保存好,一会要用到
  00401076  |.  6A 40         push    40
  00401078  |.  59            pop     ecx
  00401079  |.  33C0          xor     eax, eax
  0040107B  |.  8DBD CCFEFFFF lea     edi, dword ptr [ebp-134]
  00401081  |.  F3:AB         rep     stos dword ptr es:[edi]
  00401083  |.  39B5 C8FEFFFF cmp     dword ptr [ebp-138], esi
  00401089  |.  0F84 D5000000 je      00401164
  0040108F  |.  6A 04         push    4                                   ; /flProtect = 4
  00401091  |.  68 00100000   push    1000                                ; |flAllocationType = 1000 (4096.)
  00401096  |.  BF 08010000   mov     edi, 108                            ; |
  0040109B  |.  57            push    edi                                 ; |dwSize => 108 (264.)
  0040109C  |.  56            push    esi                                 ; |lpAddress
  0040109D  |.  FF75 08       push    dword ptr [ebp+8]                   ; |hProcess
  004010A0  |.  FF15 DC904000 call    dword ptr [<&KERNEL32.VirtualAllo>  ; \VirtualAllocEx
  004010A6  |.  8945 D8       mov     dword ptr [ebp-28], eax             ;

 在 m_ThreadHandle 的虚地址空间里分配一块空间 VirMem1, 108h字节

  004010A9  |.  3BC6          cmp     eax, esi
  004010AB  |.  0F84 B3000000 je      00401164
  004010B1  |.  8D4D E0       lea     ecx, dword ptr [ebp-20]
  004010B4  |.  51            push    ecx                                 ; /pBytesWritten
  004010B5  |.  57            push    edi                                 ; |BytesToWrite => 108 (264.)
  004010B6  |.  8D8D C4FEFFFF lea     ecx, dword ptr [ebp-13C]            ; |
  004010BC  |.  51            push    ecx                                 ; |Buffer = 0012F60C
  004010BD  |.  50            push    eax                                 ; |Address = D60000
  004010BE  |.  FF75 08       push    dword ptr [ebp+8]                   ; |hProcess = 00000088 (window)
  004010C1  |.  8B1D E0904000 mov     ebx, dword ptr [<&KERNEL32.WriteP>  ; |kernel32.WriteProcessMemory
  004010C7  |.  FFD3          call    ebx                                 ; \WriteProcessMemory

Start from buffer = 0012F60C,VirMem1 is be write something,follow buffer to point address on data window,We can find that 0008093E is handle of Edit and 772DF3B7 is SendMessage address.
Then look down:

  004010C9  |.  BE EB114000   mov     esi, 004011EB
  004010CE  |.  81EE CB114000 sub     esi, 004011CB
  004010D4  |.  89B5 C0FEFFFF mov     dword ptr [ebp-140], esi
  004010DA  |.  6A 40         push    40                                  ; /flProtect = 40 (64.)
  004010DC  |.  68 00100000   push    1000                                ; |flAllocationType = 1000 (4096.)
  004010E1  |.  56            push    esi                                 ; |dwSize => 20 (32.)
  004010E2  |.  6A 00         push    0                                   ; |lpAddress = NULL
  004010E4  |.  FF75 08       push    dword ptr [ebp+8]                   ; |hProcess = 00000088 (window)
  004010E7  |.  FF15 DC904000 call    dword ptr [<&KERNEL32.VirtualAllo>  ; \VirtualAllocEx

VirtualAlloc VirMem2,

  004010ED  |.  8945 D4       mov     dword ptr [ebp-2C], eax               ;  分配的内存地址: D70000
  004010F0  |.  85C0          test    eax, eax
  004010F2  |.  74 6E         je      short 00401162
  004010F4  |.  8D4D E0       lea     ecx, dword ptr [ebp-20]
  004010F7  |.  51            push    ecx                                   ; /pBytesWritten
  004010F8  |.  56            push    esi                                   ; |BytesToWrite => 20 (32.)
  004010F9  |.  68 CB114000   push    004011CB                              ; |Buffer = ViewPass.004011CB
  004010FE  |.  50            push    eax                                   ; |Address = D70000
  004010FF  |.  FF75 08       push    dword ptr [ebp+8]                     ; |hProcess = 00000088 (window)
  00401102  |.  FFD3          call    ebx                                   ; \WriteProcessMemory

Buffer = ViewPass.004011CB,Right menu select "Disassembly",show it:

  004011CB   .  56                    push    esi
  004011CC   .  8B7424 08             mov     esi, dword ptr [esp+8]
  004011D0   .  8D46 08               lea     eax, dword ptr [esi+8]
  004011D3   .  50                    push    eax
  004011D4   .  68 00010000           push    100
  004011D9   .  6A 0D                 push    0D
  004011DB   .  FF36                  push    dword ptr [esi]
  004011DD   .  FF56 04               call    dword ptr [esi+4]
  004011E0   .  80A6 07010000 00      and     byte ptr [esi+107], 0
  004011E7   .  5E                    pop     esi
  004011E8   .  C2 0400               retn    4

Next watch,Later analyse what to do.

  00401104  |.  8D45 DC       lea     eax, dword ptr [ebp-24]
  00401107  |.  50            push    eax                                   ; /lpThreadId
  00401108  |.  33F6          xor     esi, esi                              ; |
  0040110A  |.  56            push    esi                                   ; |dwCreationFlags => 0
  0040110B  |.  FF75 D8       push    dword ptr [ebp-28]                    ; |lpParameter => 00D60000
  0040110E  |.  FF75 D4       push    dword ptr [ebp-2C]                    ; |lpStartAddress = 00D70000
  00401111  |.  56            push    esi                                   ; |dwStackSize => 0
  00401112  |.  56            push    esi                                   ; |lpThreadAttributes => 0
  00401113  |.  FF75 08       push    dword ptr [ebp+8]                     ; |hProcess = 00000088 (window)
  00401116  |.  FF15 E4904000 call    dword ptr [<&KERNEL32.CreateRemoteT>  ; \CreateRemoteThread   

m_ThreadHandle create a process,m_ThreadHandle through OpenProcess to get when create password be create.lpStartAddress = 00D70000 The thread create to finished.Software will execute from here on.  lpParameter => 00D60000,That is transmitt parameter for the thread.

Analyse VirMem2 to write code.
  004011CB   .  56            push    esi           
  004011CC   .  8B7424 08     mov     esi, dword ptr [esp+8]       ;参数 00D60000   
  004011D0   .  8D46 08       lea     eax, dword ptr [esi+8]       ;00D60008,save passwd  
  004011D3   .  50            push    eax                          ;WM_GETTEXT get string address     
  004011D4   .  68 00010000   push    100                          ;最多返回100h个字符   
  004011D9   .  6A 0D         push    0D                           ;WM_GETTEXT   
  004011DB   .  FF36          push    dword ptr [esi]              ;Password's handle
  004011DD   .  FF56 04       call    dword ptr [esi+4]            ;SendMessage's address
  004011E0   .  80A6 07010000>and     byte ptr [esi+107], 0        ;'\0 '
  004011E7   .  5E            pop     esi
  004011E8   .  C2 0400       retn    4

Recalled the call doing:
1. push parameter
2. push return address
3. call interrupt
4. return from interrupt


New thread take as a function,Assume esp to point 00000018,Get the model.

    Stack         Content
    000010      push esi
    000014      return address
    000018      for thread transmit parameter 00D60000
    00001C 
    000020
    000024

Main analyse finished,Watch next:

  0040111C  |.  8945 E4       mov     dword ptr [ebp-1C], eax
  0040111F  |.  3BC6          cmp     eax, esi
  00401121  |.  74 3F         je      short 00401162
  00401123  |.  6A FF         push    -1                                    ; /Timeout = INFINITE
  00401125  |.  50            push    eax                                   ; |hObject = 00000098 (window)
  00401126  |.  FF15 EC904000 call    dword ptr [<&KERNEL32.WaitForSingle>  ; \WaitForSingleObject
 
  0040112C  |.  8D45 E0       lea     eax, dword ptr [ebp-20]
  0040112F  |.  50            push    eax                                   ; /pBytesRead
  00401130  |.  57            push    edi                                   ; |BytesToRead => 108 (264.)
  00401131  |.  8D85 C4FEFFFF lea     eax, dword ptr [ebp-13C]              ; |
  00401137  |.  50            push    eax                                   ; |Buffer = 0012F60C
  00401138  |.  FF75 D8       push    dword ptr [ebp-28]                    ; |pBaseAddress = D60000
  0040113B  |.  FF75 08       push    dword ptr [ebp+8]                     ; |hProcess = 00000088 (window)
  0040113E  |.  FF15 90904000 call    dword ptr [<&KERNEL32.ReadProcessMe>  ; \ReadProcessMemory

Get passwd finished.

Flow:
1.Get edit's handle.
2.GetWindowThreadProcessId() get to create edit's id.
3.OpenProcess(); Open the thread's object,Get the object's HANDLE;
4.Virtual memory at remote thread,write my code.
5.Create remote thread to create my code.
6.Return result.
7.Free momery.

Attach code:

code:
 //定义全局变量
  static BYTE RemoteCode[]=
  {
    "\x56\x8B\x74\x24\x08\x8D\x46\x08"

    "\x50\x68\x00\x01\x00\x00\x6A\x0D"

    "\xFF\x36\xFF\x56\x04\x80\xA6\x07"

    "\x01\x00\x00\x00\x5E\xC2\x04\x00"

  };

  struct Parameter{

    HWND    hWnd;

    FARPROC    pProc;

    DWORD    dwBuffer[128];

    Parameter()
    {

      hWnd  =0;

      pProc =0;

      memset(dwBuffer,0,sizeof(dwBuffer));

    }

  }; 

  Parameter RemoteParmeter;

code:
void CPWDLookDlg::GetPassWord(HWND hWnd)
{

    try{

      RemoteParmeter.hWnd = hWnd;

      DWORD  m_ThreadID = 0;

      GetWindowThreadProcessId(hWnd,&m_ThreadID);

      HANDLE  m_ThreadHandle = ::OpenProcess(0x43A,FALSE,m_ThreadID);

      if(!m_ThreadHandle)  { return; }

      HMODULE m_Usr32Mod = GetModuleHandle("user32");

      FARPROC m_SendMessageFun = GetProcAddress(m_Usr32Mod,"SendMessageA");

      RemoteParmeter.pProc = m_SendMessageFun;

      LPVOID  m_VirMem1 = VirtualAllocEx(m_ThreadHandle,NULL,sizeof(RemoteParmeter),MEM_COMMIT,PAGE_READWRITE);

      if(!m_VirMem1) { return; }

      if(!WriteProcessMemory(m_ThreadHandle,m_VirMem1, &RemoteParmeter,sizeof(RemoteParmeter),NULL)) {return;}

      LPVOID  m_VirMem2 = VirtualAllocEx(m_ThreadHandle,NULL,sizeof(RemoteCode),MEM_COMMIT,PAGE_EXECUTE_READWRITE);

      if(!m_VirMem2) { return; }

      if(!WriteProcessMemory(m_ThreadHandle,m_VirMem2, RemoteCode,sizeof(RemoteCode),NULL)){return;}

      HANDLE m_RemoteThreadHandle =
        CreateRemoteThread(m_ThreadHandle,NULL,NULL,(LPTHREAD_START_ROUTINE)m_VirMem2,m_VirMem1,NULL,NULL);

      if(!m_RemoteThreadHandle) { return; }

      WaitForSingleObject(m_RemoteThreadHandle,INFINITE);

      if(!ReadProcessMemory(m_ThreadHandle,m_VirMem1 ,&RemoteParmeter,sizeof(RemoteParmeter),NULL)) {return;}

      CString m_strPwd;

      m_strPwd.Format("%s",RemoteParmeter.dwBuffer);

      m_ediPWord.SetWindowText(m_strPwd);

      VirtualFreeEx(m_ThreadHandle,m_VirMem1,0,MEM_RELEASE);

      VirtualFreeEx(m_ThreadHandle,m_VirMem2,0,MEM_RELEASE);

      DWORD lpExitCode;

      GetExitCodeThread(m_RemoteThreadHandle ,&lpExitCode);

      CloseHandle(m_RemoteThreadHandle);

      CloseHandle(m_ThreadHandle);

    }catch(...)

    {
      AfxMessageBox("Error!");
    }

}

Sunday, July 31, 2011

.Net reverberate unpack sheller

Author:rick
This is main code:

void DumpAssembly(Assembly ass,string path) //Entry function

void DumpType(Type tp, BinaryWriter sw) //enum all type call

void DumpMethod(MethodBase mb, BinaryWriter sw) //enum all method call
{
MethodBody mbd = mb.GetMethodBody();
if (mbd == null)
return;
SetOffset(sw, mb.MetadataToken);

WriteHeader(sw, mbd);

WriteILCode(sw, mbd);

WriteSEH(sw, mbd);

}



代码:

--------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Windows.Forms;
namespace testdd
{
    public class Class1
    {
        private bool IsTiny(MethodBody mbd)
        {
            if(mbd.MaxStackSize>8)
                return false;//
            //if(mbd.LocalSignatureMetadataToken != 0)
            //    return false;
            if(mbd.LocalVariables.Count>0)
                return false;
            if(mbd.ExceptionHandlingClauses.Count>0)
                return false;
            if(mbd.GetILAsByteArray().Length>63)
                return false;
            return true;
        }

        private bool IsSEHTiny(MethodBody mb)
        {
            int n = mb.ExceptionHandlingClauses.Count;
            int datasize = n * 12 + 4;
            if (datasize > 255)
                return false;
            foreach(ExceptionHandlingClause ehc in mb.ExceptionHandlingClauses)
            {
                if (ehc.HandlerLength > 255)
                    return false;
                if (ehc.TryLength > 255)
                    return false;
                if (ehc.TryOffset > 65535)
                    return false;
                if (ehc.HandlerOffset > 65535)
                    return false;
            }
            return true;
        }
        private void WriteHeader(BinaryWriter bw,MethodBody mb)
        {
            int codesize = mb.GetILAsByteArray().Length;
            if(IsTiny(mb))
            {
                byte bt = 2;
                bt = (byte)(bt + codesize * 4);
                bw.Write(bt);
                return;
            }
            //fat mode here
            byte fg = 3;//fat flag
            if (mb.LocalVariables.Count > 0 && mb.InitLocals)
                fg |= 0x10;
            if (mb.ExceptionHandlingClauses.Count > 0)
                fg |= 0x8;
            bw.Write(fg);// byte 1           
            bw.Write((byte)0x30);//byte 2
            bw.Write((ushort)mb.MaxStackSize);// byte 3, 4
            bw.Write(codesize);//byte 5-8
            bw.Write(mb.LocalSignatureMetadataToken);//byte 9-12
        }
        private void WriteILCode(BinaryWriter bw,MethodBody mb)
        {
            int codesize = mb.GetILAsByteArray().Length;
            bw.Write(mb.GetILAsByteArray());

            //对齐 4 bytes
            int ig = codesize & 3;
            if (ig == 0)
                return;
            if (mb.ExceptionHandlingClauses.Count == 0)
                return;//无SEH;
            ig = 4 - ig;
            for(int i=0; i<ig;i++)
            {
                bw.Write((byte)0);
            }
        }
        private void WriteTinySEHHeader(BinaryWriter bw,MethodBody mb)
        {
            int n = mb.ExceptionHandlingClauses.Count;
            int datasize = n * 12 + 4;
            bw.Write((byte)1);
            bw.Write((byte)datasize);
            bw.Write((byte)0);
            bw.Write((byte)0);
        }
        private void WriteFatSEHHeader(BinaryWriter bw, MethodBody mb)
        {
            int n = mb.ExceptionHandlingClauses.Count;
            int datasize = n * 24 + 4;
            datasize = datasize * 0x100 + 0x41;
            bw.Write(datasize);
        }
        private void WriteSeHTinyRow(BinaryWriter bw,ExceptionHandlingClause ehc)
        {
            ushort flag = 0;
          
            if (ehc.Flags == ExceptionHandlingClauseOptions.Filter)
                flag += 1;
            if (ehc.Flags == ExceptionHandlingClauseOptions.Fault)
                flag += 4;
            if (ehc.Flags == ExceptionHandlingClauseOptions.Finally)
                flag += 2;
            bw.Write(flag);

            bw.Write((ushort)ehc.TryOffset);
            bw.Write((byte)ehc.TryLength);

            bw.Write((ushort)ehc.HandlerOffset);
            bw.Write((byte)ehc.HandlerLength);
            object obj = new object();
            if (ehc.Flags == ExceptionHandlingClauseOptions.Clause /*|| ehc.CatchType != obj.GetType()*/)
                bw.Write(GetTypeToken(ehc.CatchType));
            else
                bw.Write(ehc.FilterOffset);

        }

        private void WriteSeHFatRow(BinaryWriter bw, ExceptionHandlingClause ehc)
        {
            int flag = 0;
          
            if (ehc.Flags == ExceptionHandlingClauseOptions.Filter)
                flag += 1;
            if (ehc.Flags == ExceptionHandlingClauseOptions.Fault)
                flag += 4;
            if (ehc.Flags == ExceptionHandlingClauseOptions.Finally)
                flag += 2;
            bw.Write(flag);//
           
            bw.Write(ehc.TryOffset);
            bw.Write(ehc.TryLength);

            bw.Write(ehc.HandlerOffset);
            bw.Write(ehc.HandlerLength);
            object obj = new object();
            if (ehc.Flags == ExceptionHandlingClauseOptions.Clause /*|| ehc.CatchType != obj.GetType()*/)
                bw.Write(GetTypeToken(ehc.CatchType));
            else
                bw.Write(ehc.FilterOffset);
           

        }
   
        private void WriteSEH(BinaryWriter bw,MethodBody mb)
        {
            if (mb.ExceptionHandlingClauses.Count == 0)
                return;
            bool bTiny = IsSEHTiny(mb);
            if (bTiny)
                WriteTinySEHHeader(bw, mb);
            else
                WriteFatSEHHeader(bw, mb);
            foreach (ExceptionHandlingClause ehc in mb.ExceptionHandlingClauses)
            {
                if (bTiny)
                    WriteSeHTinyRow(bw, ehc);
                else
                    WriteSeHFatRow(bw, ehc);
            }
        }

      
        public static void Dump()
        {
            Class1 cls = new Class1();
            cls.DoIt();
        }
        public Class1()
        {
            //nil
            int i = 0;
            try
            {
                string s = "";
                if (s == "")
                    i = 2;

            }
            catch(Exception ex)
            {
                MessageBox.Show("err" + ex.ToString());
            }
        }

        protected void DoIt()
        {
            Assembly ass = Assembly.GetEntryAssembly();
            DumpAssembly(ass,@"D:\4.0.1.0\dumped.exe");
          
        }

        /// <summary>
        /// Dump程序集的 IL字节代码到指定目录;
        /// </summary>
        /// <param name="ass"></param>
        /// <param name="path"></param>
        private void DumpAssembly(Assembly ass,string path)
        {
            //////////////////////////////////////////////////////////////////////////
            if(!testdd.com.WrapperClass.MetaInit(ass.Location))
            {
                MessageBox.Show("error meta");
                return;
            }
            FileStream fs = new FileStream(path, System.IO.FileMode.Open,FileAccess.Write);
            BinaryWriter bw = new BinaryWriter(fs);

            Type[] tps = ass.GetTypes();
            for(int i=0; i< tps.Length; i++)
            {
                DumpType(tps[i], bw);
            }
            bw.Flush();
            bw.Close();
            bw = null;
            fs.Close();
            fs = null;
            MessageBox.Show("ok");
        }
        private void DumpType(Type tp, BinaryWriter sw)
        {
            BindingFlags bf = BindingFlags.NonPublic | BindingFlags.DeclaredOnly |
               BindingFlags.Public | BindingFlags.Static
               | BindingFlags.Instance;

           
            MemberInfo[] mbis = tp.GetMembers(bf);
            for (int i = 0; i < mbis.Length; i++)
            {
                MemberInfo mbi = mbis[i];               
               
                try
                {
                    if (mbi.MemberType == MemberTypes.Method || mbi.MemberType == MemberTypes.Constructor)
                    {
                        DumpMethod((MethodBase)mbi, sw);
                    }
                }
                catch(Exception)
                {
                  
                }

            }
          
        }

        private void DumpMethod(MethodBase mb, BinaryWriter sw)
        {
            MethodBody mbd = mb.GetMethodBody();
            if (mbd == null)
                return;
            SetOffset(sw, mb.MetadataToken);

            WriteHeader(sw, mbd);

            WriteILCode(sw, mbd);

            WriteSEH(sw, mbd);  

        }
        private int GetTypeToken(Type tp)
        {
            if (tp.Assembly == Assembly.GetEntryAssembly())
                return tp.MetadataToken;
            Assembly ass = Assembly.GetEntryAssembly();
            uint tk = testdd.com.WrapperClass.GetTypeToken(tp);
            if(tk == 0)
            {
                MessageBox.Show("error tk");
                return 0x100005f;
            }
            return (int)tk;
        }
        private void SetOffset(BinaryWriter bw, int mbtk)
        {
            uint token = (uint)mbtk;
            uint offsetrva = testdd.com.WrapperClass.GetMehodRVA(token);
            int offsetra = (int)(offsetrva - 0x1000);
            bw.Seek(offsetra, SeekOrigin.Begin);
        }
    }

   
}