⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ildriver.c

📁 IceLight逆向出来的源代码。 有idb文件和c文件
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 
					Icelight's Driver Source Code	reversed by achillis[R.C.T]

blog:	http://hi.baidu.com/_achillis
QQ	:	344132161
*/

#include "ntifs.h"
#include "myRootkit.h"
#include "LDasm.h"

//类型声明
typedef HANDLE HWND;
typedef HWND HDESK;
typedef unsigned int UINT;
typedef unsigned char BYTE;
typedef UINT_PTR WPARAM;
typedef ULONG_PTR LPARAM;

typedef HWND
(*pfnNtUserFindWindowEx)(
	HWND  hwndParent,
	HWND  hwndChildAfter,
	PUNICODE_STRING  ucClassName,
	PUNICODE_STRING  ucWindowName,
	DWORD dwUnknown
	);

typedef BOOL
(*pfnNtUserPostMessage)(
	HWND hWnd,
	UINT Msg,
	WPARAM wParam,
	LPARAM lParam
	);

typedef NTSTATUS
(*pfnNtUserBuildHwndList)(
	HDESK hDesktop,
	HWND hwndParent,
	BOOLEAN bChildren,
	ULONG dwThreadId,
	ULONG lParam,
	HWND* pWnd,
	PULONG pBufSize
	);

typedef HWND
(*pfnNtUserGetForegroundWindow)(VOID);

typedef DWORD
(*pfnNtUserQueryWindow)(
	HWND hWnd,
	DWORD Index
	);

typedef HWND
(*pfnNtUserWindowFromPoint)(
	LONG X,
	LONG Y
	);

typedef BOOL
(*pfnNtUserPostThreadMessage)(
	DWORD idThread,
	UINT Msg,
	WPARAM wParam,
	LPARAM lParam
	);

typedef HWND
(*pfnNtUserSetParent)(
	HWND hWndChild,
	HWND hWndoldParent
	);

typedef NTSTATUS
(*pfnNtOpenProcess)(
	PHANDLE ProcessHandle,
	ACCESS_MASK DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes,
	PCLIENT_ID ClientId
	);

typedef NTSTATUS
(*pfnNtOpenThread)(
	PHANDLE ThreadHandle,
	ACCESS_MASK DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes, 
	PCLIENT_ID ClientId
	);

typedef NTSTATUS
(*pfnZwTerminateThread)(
	HANDLE ThreadHandle,
	NTSTATUS ExitStatus
);

typedef NTSTATUS
(*pfnPspTerminateThreadByPointer)(
	PETHREAD Thread,
	NTSTATUS ExitStatus
);

//-------------------------------------------------------------------------------------------
//两个数组,用于反汇编用
DWORD OpCode[256]={0x4000,0x4000,0x4000,0x4000,0x100,0x2000,0x8000,0x8000,0x4000,0x4000,
				 0x4000,0x4000,0x100,0x2000,0x8000,0x10000,0xC000,0x4000,0xC000,0x4000,
				 0x8100,0xA000,0x8000,0x8000,0xC000,0x4000,0x4000,0x4000,0x8100,0xA000,
				 0x8000,0x8000,0x4000,0x4000,0x4000,0x4000,0x100,0x2000,0x8080,0x8000,
				 0x4000,0x4000,0x4000,0x4000,0x100,0x2000,0x8080,0x8000,0x4000,0x4000,
				 0x4000,0x4000,0x100,0x2000,0x8080,0x8000,0x4000,0x4000,0x4000,0x4000,
				 0x100,0x2000,0x8080,0x8000,0,0,0,0,0x8000,0,0,0,0,0,0,0,0x8000,0,0,0,
				 0,0,0,0,0,0,0,0,0,0,0,0,0x8000,0,0,0,0x8000,0x8000,0xC000,0xC000,0x80,
				 0x8080,0x20,0x10,0x2000,0x6000,0x100,0x4100,0x8000,0x8000,0x8000,0x8000,
				 0x28100,0x28100,0x20100,0x20100,0x20100,0x20100,0x20100,0x20100,0x20100,
				 0x20100,0x28100,0x28100,0x20100,0x20100,0x20100,0x20100,0x4100,0x6000,
				 0xC100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
				 0xC000,0x4000,0xC000,0x4000,0,0,0,0x8000,0x8000,0x8000,0x8000,0x8000,
				 0x8000,0,0xA200,0,0x8000,0x8000,0x8000,0x8000,0x1000,0x1000,0x1000,0x1000,
				 0,0,0,0,0x100,0x2000,0,0,0,0x8000,0,0x8000,0x100,0x100,0x100,0x100,0x100,
				 0x100,0x8100,0x8100,0x2000,0x2000,0x2000,0x2000,0xA000,0x2000,0x2000,
				 0x2000,0x4100,0x4100,0x40200,0x40000,0xC000,0xC000,0x4100,0x6000,0x300,
				 0,0x48200,0x48000,0x8000,0x100,0x8000,0x48000,0x4000,0x4000,0x4000,0x4000,
				 0x8100,0x8100,0x8000,0x8000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
				 0x4000,0x4000,0x28100,0x28100,0x20100,0x20100,0x8100,0x8100,0x8100,0x8100,
				 0x22000,0x62000,0xA200,0x60100,0x8000,0x8000,0x8000,0x8000,0x8008,0x8000,
				 0x40,0x40,0x8000,0x8000,0x4000,0x4000,0,0,0x8000,0x8000,0,0,0x4000,0x4000}; 
DWORD OpCode2[256]={0x4000,0x4000,0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0,0xFFFFFFFF,0,0,
			0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x4000,0x4000,0x4000,
			0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
			0x4000,0x4000,0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x22000,0x22000,0x22000,0x22000,
			0x22000,0x22000,0x22000,0x22000,0x22000,0x22000,0x22000,0x22000,
			0x22000,0x22000,0x22000,0x22000,0x4000,0x4000,0x4000,0x4000,0x4000,
			0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
			0x4000,0,0,0,0x4000,0x4100,0x4000,0xFFFFFFFF,0xFFFFFFFF,0,0,0,0x4000,
			0x4100,0x4000,0xFFFFFFFF,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
			0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0x4100,0x4000,0x4000,0x4000,0x4000,
			0x4000,0x4000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0,0,0,0,0,0x100,0,0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
			0xFFFFFFFF,0xFFFFFFFF}; 
char byte_12C84[4]; //Unknow
//存储自己的EPROCESS
ULONG EPROCESSArray[100]; 

ULONG g_oplen; 
ULONG g_FakeProcLen; 
BOOL bHookPspTerminateThreadByPointerSuccess; 
BOOL bIsKeInsertQueueApcNeverModifyed=0; 
//保存原始cr0的值
ULONG g_OriginalCr0; 
//Shadow SSDT中相关函数的索引
ULONG IdNtUserFindWindowEx; 
ULONG IdNtUserGetForcegroundWindow; 
ULONG IdNtUserQueryWindow; 
ULONG IdNtUserBuildHwndList; 
ULONG IdNtUserPostThreadMessage; 
ULONG IdNtUserWindowFromPoint; 
ULONG IdNtUserPostMessage; 
ULONG IdNtUserSetParent; 
//两个链表的偏移
ULONG ThreadListEntryOffsetInEThread; 
ULONG ThreadListHeadOffstInEprocess; 
PSERVICE_DESCRIPTOR_TABLE_SHADOW pKeServiceDescriptorTableShadow; 
KSPIN_LOCK g_SpinLock; 
PETHREAD g_IceThread; 
PKNORMAL_ROUTINE ApcNormalRoutine; 
PKKERNEL_ROUTINE ApcKernelRoutine; 
PKRUNDOWN_ROUTINE ApcRundownRoutine; 
PEPROCESS csrssEPROCESS; 
//保存原始SSDT值
ULONG g_OriginalNtOpenProcess; 
ULONG g_OriginalNtOpenThread; 
//保存自己的Pid和Tid
HANDLE g_IcePid; 
HANDLE g_IceTid; 
ULONG dwNtBuildNumber; 
HWND LastTopWindowHandle; 
ULONG PspTerminateThreadByPointer;
//函数变量声明
pfnNtUserWindowFromPoint  oldNtUserWindowFromPoint; 
pfnNtUserPostThreadMessage oldNtUserPostThreadMessage; 
pfnNtUserSetParent oldNtUserSetParent; 
pfnNtUserGetForegroundWindow oldNtUserGetForcegroundWindow; 
pfnNtUserQueryWindow oldNtUserQueryWindow; 
pfnNtUserPostMessage oldNtUserPostMessage; 
pfnNtUserBuildHwndList oldNtUserBuildHwndList; 
pfnNtUserFindWindowEx oldNtUserFindWindowEx; 
pfnNtOpenThread trueNtOpenThread; 
pfnNtOpenProcess trueNtOpenProcess; 
pfnZwTerminateThread  myZwTerminateThread; 
pfnPspTerminateThreadByPointer newPspTerminateThreadByPointer;


//-------------------------------------------------------------------------


HWND
newNtUserFindWindowEx(
	HWND  hwndParent,
	HWND  hwndChildAfter,
	PUNICODE_STRING  ucClassName,
	PUNICODE_STRING  ucWindowName,
	DWORD dwUnknown
  );

BOOL
newNtUserPostMessage(
	HWND hWnd,
	UINT Msg,
	WPARAM wParam,
	LPARAM lParam
	);

NTSTATUS
newNtUserBuildHwndList(
	HDESK hDesktop,
	HWND hwndParent,
	BOOLEAN bChildren,
	ULONG dwThreadId,
	ULONG lParam,
	HWND* pWnd,
	PULONG pBufSize
	);

HWND
newNtUserGetForegroundWindow(VOID);

DWORD
newNtUserQueryWindow(
	HWND hWnd,
	DWORD Index
	);

HWND
newNtUserWindowFromPoint(
	LONG X,
	LONG Y
	);

BOOL
newNtUserPostThreadMessage(
	DWORD idThread,
	UINT Msg,
	WPARAM wParam,
	LPARAM lParam
	);

HWND
newNtUserSetParent(
	HWND hWndChild,
	HWND hWndNewParent
	);

NTSTATUS
myNtOpenProcess (
	PHANDLE ProcessHandle,
	ACCESS_MASK DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes,
	PCLIENT_ID ClientId
    );

NTSTATUS
myNtOpenThread(
	PHANDLE ThreadHandle,
	ACCESS_MASK DesiredAccess,
	POBJECT_ATTRIBUTES ObjectAttributes, 
	PCLIENT_ID ClientId
	);
NTSTATUS
myPspTerminateThreadByPointer(
	PETHREAD Thread,
	NTSTATUS ExitStatus
    );

void TerminateThreadApcRoutine(
	KAPC *Apc,
	PKNORMAL_ROUTINE *NormalRoutine,
	PVOID *NormalContext,
	PVOID *SystemArgument1,
	PVOID *SystemArgument2
	);
	
NTSTATUS
DeviceControlProduce(
	PFILE_OBJECT FileObject,
	ULONG Unknow2,
	PVOID SystemBuffer,
	ULONG InputBufferLen,
	PVOID UserBuffer,
	ULONG OutputBufferLength,
	ULONG ControlCode,
	PIO_STATUS_BLOCK pIoStatusBlock
	);

ULONG
CheckSepcialApcRoute(
	PVOID targetThread,
	PKKERNEL_ROUTINE KernelRoutine,
	PKRUNDOWN_ROUTINE RundownRoutine,
	PKNORMAL_ROUTINE  NormalRoutine
	);

//----------------------------------------------------函数介绍-------------------------------------------
//一个小的反汇编部分,用于计算指令长度
int __stdcall GetOpLen(BYTE *p);
//从PsTerminateSystemThread中获取ETHREAD中Flag的偏移
WORD GetThreadFlagOffset(void);
//检查并对KeInsertQueueApc进行Hook或Unhook,可能不准确
void CheckAndHookorUnHookKeInsertQueueApc(void);
//HookProc for KeInsertQueueApc,为了获取PsExitSpecialApc
void myKeInsertQueueApc(void);
//从KeAddSystemServiceTable中搜索Shadow SSDT的地址
ULONG SearchShadowSSDT(void);
//根据不同系统版本设置Shadow SSDT中几个要Hook的函数的索引
ULONG SetShdowSSDTFunID(void);
//查句柄的信息,SystemHandleInformation
char* GetSystemHandleInfo(SYSTEM_INFORMATION_CLASS SystemInformationClass);
//获取Csrss.exe的pid,为Hook/Unhook Shadow SSDT做准备
HANDLE GetCsrssPid(void);
//自己搜索ZwTerminateThread的地址(为何?)
BOOL GetZwTerminateThreadAddr(void);
//只是调用了SearchShadowSSDT而已
BOOL GetShdowSSDTAddr(void);
//Hook SSDT中的NtOpenProcess和NtOpenThread
BOOL HookNtOpenProcessAndThread(void);
//驱动卸载时恢复SSDT Hook
BOOL UnHookSSDT(void);
//把自己的EPROCESS放到一个数组中
BOOL StoreEPROCESS(ULONG eProcess);
//I don't know how this function does,just something about eprocess
BOOL SomeThingAboutEprocess(ULONG eProess);
//判断是否自己的EPROCESS,用于Hook函数中决定是否放行
BOOL IsMyEprocess(PVOID eProess);
//对KeInsertQueueApc进行Header Inline Hook
BOOL InlineHookKeInsertQueueApc(void);
//对PspTerminateThreadByPointer进行Header Inline Hook,Hook方式为一字节两次跳转
BOOL InlineHookPspTerminateThreadByPointer(PVOID FunAddr, PVOID HookProc);
//在PspTerminateSystemThread中搜索PspTerminateThreadByPointer的地址,以进行Hook
BOOL SearchPspTermiThreadAddress(void);
//调用了搜索地址,完成Hook等一系列动作而已
BOOL SetOneByteHookOnPspTerminateThreadByPointer(void);
//自己实现的Sleep函数
BOOL IceSleep(int time);
//强制删除文件
BOOL IceForceDeleteFileByHandle(HANDLE FileHandle);
//强制删除文件,调用了上面那个
BOOL IceForceDeleteFile(HANDLE hFileHandle);
//使用了多种安全措施进行memcpy,但还是不够安全
BOOL IceSafeMemcpy(PVOID TargetAddr, PVOID SourceAddr, int len);
//简单调用PsLookupProcessByProcessId加判断
PEPROCESS  IceGetEprocessByPid(ULONG pid);
//模仿PsGetNextProcessThread
PKTHREAD IceGetNextProcessThread(PVOID eProess, PVOID eThread);
//投递APC杀线程,准备了两个APC,获取系统PsExitSpecialApc就用自带的
ULONG  IceKillThread(PKTHREAD ethread);
//驱动卸载时Unhook PspTerminateThreadByPointer
void UnHookPspTerminateThread(void);
//简单包装IoCreateFile
HANDLE  IceCreateFile(PCWSTR SourceString, ACCESS_MASK DesiredAccess, ULONG ShareAccess); 
//根据系统版本设置EPROCESS和ETHREAD两个结构中线程相关链表的偏移,为IceGetNextProcessThread服务
ULONG  SetThreadListOffset(void);
//通过LDasm引擎计算myKeInsertQueueApc的有效代码长度
ULONG  GetFakeCodeLengthForKeInsertQueueApc();
//ForceDeleteFile时用到的完成例程
NTSTATUS CompleteRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
//下面四个就不介绍了
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS DispatchIoControl(PDEVICE_OBJECT pDeviceObject, PIRP PIrp);
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
void DriverUnload(PDRIVER_OBJECT	pDriverObject);

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, DispatchCreateClose)
#pragma alloc_text(PAGE, DispatchIoControl)
#pragma alloc_text(PAGE, DriverUnload)
#endif // ALLOC_PRAGMA

WORD GetThreadFlagOffset(void)
{
  char* pFn;
  int len; 
  char *pNextOpCode; 
  // 该函数从PsTerminateThread中搜索flag标志的偏移
  for ( pFn = (char*)PsTerminateSystemThread; pFn < (char*)PsTerminateSystemThread + 0x100; pFn += len )
  {
    len = SizeOfCode(pFn, &pNextOpCode);
    if ( !len )
      break;
    if ( *(WORD *)pNextOpCode == 0x80F6 )
      return *(WORD *)(pNextOpCode + 2);
  }
  return 0;
}


ULONG
CheckSepcialApcRoute(
	PVOID targetThread,
	PKKERNEL_ROUTINE KernelRoutine,
	PKRUNDOWN_ROUTINE RundownRoutine,
	PKNORMAL_ROUTINE  NormalRoutine)
{
  ULONG result; 
  //该函数为了获取PsExitSpecialApc,即下面的KernelRoutine
  result = (ULONG)targetThread;
  if (targetThread ==  (PVOID)g_IceThread )
  {
    if ( KernelRoutine )
    {
      result = (ULONG)NormalRoutine;
      if ( NormalRoutine )
      {
        if ( !ApcKernelRoutine )
        {
          ApcKernelRoutine = KernelRoutine;
          ApcRundownRoutine = RundownRoutine;
          ApcNormalRoutine = NormalRoutine;
        }
      }
    }
  }
  return result;
}


void CheckAndHookorUnHookKeInsertQueueApc(void)
{
  char *pfn; 
  KIRQL oldIRQL; 

  if ( g_oplen )
  {
    pfn = (char *)KeInsertQueueApc;
    if ( bIsKeInsertQueueApcNeverModifyed )
      pfn = (char *)KeInsertQueueApc + 2;
    if ( MmIsAddressValid(pfn) )
    {
      WPOFF();
      oldIRQL = KeRaiseIrqlToDpcLevel();
	  //判断myKeInsertQueueApc是否已经Hook了
      if ( g_oplen != 5 || *((BYTE *)myKeInsertQueueApc + g_FakeProcLen) != 0xE9 )
      {
		  //若Hook过,则把KeInsertQueueApc的函数头拷回来,5字节,还原Hook
		  memcpy(pfn, (char *)myKeInsertQueueApc + g_FakeProcLen, g_oplen);
		
      }
      else
      {
		  //若未Hook,则开始对KeInsertQueueApc进行Hook
		  *pfn = 0xE9;
		  *(DWORD *)(pfn + 1) =*(DWORD *)((char *)myKeInsertQueueApc + g_FakeProcLen + 1)
							+(char *)myKeInsertQueueApc - pfn + g_FakeProcLen;
      }
      KeLowerIrql(oldIRQL);
      WPON();
      g_oplen = 0;
    }
  }
}


__declspec( naked )  int __stdcall GetOpLen(BYTE *p)
{
	//能力有限,还原成的C版得到的结果时对时错,为保证准确只好使用原版汇编
	_asm
	{
		push    ebp
		mov     ebp, esp
		sub     esp, 0x2C
		mov     edx, [ebp+8]
		mov     ax, [edx]
		push    edi
		xor     edi, edi
		test    ax, ax
		mov     byte ptr [ebp-0x2B], 0x4
		mov     byte ptr [ebp-0x2C], 0x4
		jz      oplab_5
		cmp     ax, 0xFFFF
		jz      oplab_5
		mov     cl, al
		lea     eax, [edx+1]
		jmp     oplab_4
oplab_1: 
		test    edx, edi
		jnz     oplab_5
		or      edi, edx
		test    dl, 0x10
		jz      oplab_2
		xor     byte ptr [ebp-0x2C], 6
		jmp     oplab_3
oplab_2: 
		test    dl, 0x20
		jz      oplab_3
		xor     byte ptr [ebp-0x2B], 6
oplab_3:
		mov     cl, [eax]
		inc     eax
oplab_4: 
		movzx   edx, cl
		push	eax //
		lea		eax,OpCode//
		mov     edx, dword ptr [edx*4+eax]
		pop		eax//
		test    dl, 0xF8
		jnz     oplab_1
		or      edi, edx
		cmp     cl, 0x0F

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -