Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   утилиты - icmprange, mbrscan (https://forum.antichat.xyz/showthread.php?t=97518)

bons 22.12.2008 22:22

утилиты - icmprange, mbrscan
 
Вложений: 1
написал недавно пару консольных утилит для Windows на языке C, решил выложить, может будут кому-то полезны.

icmprange

Утилита предназначена для посылки ICMP-запросов диапазону IP-адресов. То есть это примерно то же что и запуск nmap с ключом -sP. Вывод ведется по мере поступления ICMP-ответов поэтому неотсортирован

Пример использования:
Код:

icmprange 192.168.0.1-254 1000
где 1000 - таймаут в миллисекундах

Использовать можно например там где нет надобности или возможности применить более мощные инструменты

Исходный код:
Код:

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

//Прототипы структур
typedef struct _REQUESTINFO {
        void* replyBuf;
        int ReplySize;
        UINT addr;
} REQUESTINFO,*PREQUESTINFO;

typedef struct _IPRANGE {
        BYTE Beg[4];
        BYTE End[4];
} IPRANGE,*PIPRANGE;

//Прототипы функций
typedef DWORD (WINAPI *ICMPPARSEREPLIES)(
  void* ReplyBuffer,
  DWORD ReplySize
);

typedef DWORD (WINAPI * ICMPSENDECHO2)(
        HANDLE IcmpHandle,
        HANDLE Event,
        PVOID ApcRoutine,
        PVOID ApcContext,
        UINT DestinationAddress,
        LPVOID RequestData,
        WORD RequestSize,
        PVOID RequestOptions,
        LPVOID ReplyBuffer,
        DWORD ReplySize,
        DWORD Timeout
);

typedef HANDLE (WINAPI * ICMPCREATEFILE)(void);

typedef BOOL (WINAPI * ICMPCLOSEHANDLE)(
        HANDLE IcmpHandle
);

//Глобальные переменные
UINT nTotalRequests;
ICMPPARSEREPLIES PIcmpParseReplies;
ICMPSENDECHO2 PIcmpSendEcho2;
ICMPCREATEFILE PIcmpCreateFile;
ICMPCLOSEHANDLE PIcmpCloseHandle;

/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Распознать диапазон в виде строки
PIPRANGE ParceRangeString(char* cpStr, UINT* nAddresses)
{
        UINT i, j, dwLen, b, e, n;
        PCHAR pM;
        PCHAR cpValues[4];
        PIPRANGE range;
        char buf[64];
       
        dwLen = strlen(cpStr);
        if(dwLen == 0)return NULL;       
        range = malloc(sizeof(IPRANGE));
       
        cpValues[0] = cpStr; j=1; n=1;
        for(i=0; i<dwLen; i++)
                if(cpStr[i] == '.')
                {
                        if(j == 4)
                        {
                                free(range);
                                return NULL;
                        }
                        cpValues[j++]=cpStr+i+1;
                        cpStr[i]=0;
                }
       
        if(j<4)
        {
                free(range);
                return NULL;
        }
       
        for(j=0;j<4;j++)
        {
                if((pM = strchr(cpValues[j],'-'))==NULL)
                        b = e = atol(cpValues[j]);
                else
                {
                        *(pM++)=0;
                        b=atol(cpValues[j]);
                        e=atol(pM);
                }
               
                if((b>255)||(e>255))
                {
                        free(range);
                        return NULL;
                }

                if(b>e)
                {
                        free(range);
                        return NULL;
                }
                range->Beg[j]=b;
                range->End[j]=e;
                n = n*(e-b+1);
        }
        if(nAddresses)*nAddresses = n;
        return range;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Вызывается системой после ICMP-запроса
void WINAPI IcmpCallback (PREQUESTINFO info)
{
        UINT net_addr = htonl(info->addr);
        UINT resp = PIcmpParseReplies(info->replyBuf, info->ReplySize);
       
        if(resp)printf("%s\n", inet_ntoa(*(struct in_addr*)&net_addr));
        free(info->replyBuf);
        free(info);
        nTotalRequests--;
        return;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Послать ICMP-запрос по заданному адресу
PREQUESTINFO SendPing(PVOID hICMP, UINT addr, UINT timeout)
{
        PREQUESTINFO info = malloc(sizeof(REQUESTINFO));
        UINT dwRet, iErr, addr2;

        info->addr = addr;
        info->ReplySize = 40;
       
        addr = htonl(addr);
        dwRet = 0;
        while(!dwRet)
        {
                info->replyBuf = malloc(info->ReplySize);
                dwRet = PIcmpSendEcho2(hICMP, NULL, IcmpCallback, info, addr, NULL, 0, NULL, info->replyBuf, info->ReplySize, timeout);
                if(!dwRet)
                {
                        iErr = GetLastError();
                        if(iErr == ERROR_INSUFFICIENT_BUFFER)
                        {
                                free(info->replyBuf);
                                info->ReplySize = info->ReplySize*2;
                                if(info->ReplySize > 65535)
                                {
                                        free(info);
                                        return NULL;
                                }
                                continue;
                        }
                        if(iErr == ERROR_IO_PENDING)return info;
                       
                        free(info);
                        return NULL;
                }
        }
        return NULL;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//ICMP-сканирование заданного диапазона с заданным таймаутом
void PingRange(PIPRANGE range, UINT timeout)
{
        int i0, i1, i2, i3;
        UINT addr=0, i=0;
        PVOID hICMP = PIcmpCreateFile();
       
        for(i0=range->Beg[0];i0<=range->End[0];i0++)
        {
                ((UCHAR*)&addr)[3]=i0;
                for(i1=range->Beg[1];i1<=range->End[1];i1++)
                {
                        ((UCHAR*)&addr)[2]=i1;
                        for(i2=range->Beg[2];i2<=range->End[2];i2++)
                        {
                                ((UCHAR*)&addr)[1]=i2;
                                for(i3=range->Beg[3];i3<=range->End[3];i3++)
                                {
                                        ((UCHAR*)&addr)[0]=i3;
                                        if(SendPing(hICMP, addr, timeout))i++;
                                }
                        }
                }
        }
        nTotalRequests = i;
        while(nTotalRequests>0)
        {
                SleepEx(INFINITE, TRUE);
        }
        PIcmpCloseHandle(hICMP);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int main(int argc, char** argv)
{
        UINT nAddresses, timeout = 1000;
        PIPRANGE iprange;
        WSADATA GInitData;
        HANDLE hLib;
       
        WSAStartup(0x0202, &GInitData);
        if(argc < 2)
        {
                printf(" Usage: icmpscan ip_range [timeout]\n");
                printf(" Example: icmpscan 192.168.0.1-254 5000\n");
                return -1;
        }
        if(argc == 3)
        {
                timeout = atol(argv[2]);
                if(!timeout)timeout = 1000;
        }
        hLib = LoadLibrary("Iphlpapi.dll");
        if(!hLib)
        {
                printf("Iphlpapi.dll not found\n");
                return -1;
        }
        PIcmpParseReplies        = (ICMPPARSEREPLIES)GetProcAddress(hLib, "IcmpParseReplies");
        PIcmpSendEcho2                = (ICMPSENDECHO2)GetProcAddress(hLib, "IcmpSendEcho2");
        PIcmpCreateFile                = (ICMPCREATEFILE)GetProcAddress(hLib, "IcmpCreateFile");
        PIcmpCloseHandle        = (ICMPCLOSEHANDLE)GetProcAddress(hLib, "IcmpCloseHandle");
       
        if(!PIcmpParseReplies || !PIcmpSendEcho2 || !PIcmpCloseHandle || !PIcmpCreateFile)
        {
                printf("Needed functions not available\n");
                return -1;
        }
       
        iprange = ParceRangeString(argv[1], &nAddresses);
        printf("Scan %u addresses, timeout %u ms:\n", nAddresses, timeout);
        if(!iprange)
        {
                printf("Invalid parameter\n");
                return -1;
        }
        PingRange(iprange, timeout);
        free(iprange);

        WSACleanup();
        return 0;
}


mbrscan

Утилита сканирует структуры MBR жестких дисков локального компьютера.
Пример вывода утилиты:
Код:

# MBR reader starts
HDD  Disc  Boot  Addr        Size        FS            SN          mb/gb
------------------------------------------------------------------------
HDD0  C:    +    0000003F    03A9A172    (07)NTFS      A47B02F6    29 GB
HDD0  D:    -    03A9A1F0    0EF7E8D1    (07)NTFS      32CC0564    119 GB

Код можно использовать например для расширения функционала руткита - поиск скрытых разделов, исследование жесткого диска

исходный код:

Код:

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

char FAT[]="\x01\x04\x06\x0D\x0E";

typedef struct _HARDINFO
{
        char nHard;                //номер жесткого диска
        void* hDrive;                //хэндл жесткого диска
        UINT dwSectorSize;        //размер сектора
        UINT bitsPerSector;        //количество разрядов для адресации внутри сектора
        UINT dwExtendedAddr;        //адрес расширенного раздела

} HARDINFO, *PHARDINFO;

/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Узнать диск по серийному номеру
char GetDiscBySN(UINT SN)
{
        UINT VolumeSerialNumber;
        UINT ldrives = GetLogicalDrives();
        char Drive[4]="X:\\";
        int i;
       
        for(i=2;i<25;i++)
                if((ldrives & (1<<i)) != 0)
                {
                        Drive[0] = 'A'+i;
                        switch(GetDriveType(Drive))
                        {
                                case DRIVE_CDROM:
                                break;
               
                                default:
                                GetVolumeInformation(Drive,
                                NULL,0,
                                &VolumeSerialNumber,
                                NULL,0,NULL,0
                                );
                                if(VolumeSerialNumber==SN)
                                        return Drive[0];
                        }
                }
        return 0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Узнать файловую систему диска по коду файловой системы
char* GetFileSystem(unsigned char code)
{
        int i;
       
        if((code==0x07)||(code==0x17))
                return "NTFS  ";
        if(code==0x82)
                return "ext2  ";
        if(code==0x83)
                return "ext3  ";
        if((code==0x0B)||(code==0x0C))
                return "FAT32 ";
        for(i=0;i<sizeof(FAT);i++)
                if(code==FAT[i])
                        return "FAT  ";
        return "?      ";
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Вывести текст ошибки
void AnalyzeError(int iErr, char* comment)
{
        char locBuf[1024];

        FormatMessage(
          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
          0, iErr, 0, locBuf, sizeof(locBuf), 0
        );
        CharToOem(locBuf, locBuf);
        printf("%s (%u) %s\n", comment, iErr, locBuf);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//сдвинуть указатель
int MovePointer(PHARDINFO inf, UINT secpointer)
{
        UINT iErr;
        UINT HiPointer = secpointer>>(32-inf->bitsPerSector);
        UINT LoPointer = secpointer<<(inf->bitsPerSector);

        UINT bRetValue=SetFilePointer(inf->hDrive,LoPointer,&HiPointer,FILE_BEGIN);
        if(bRetValue == -1)
        {
                iErr=GetLastError();
                if(iErr!=NO_ERROR)
                        AnalyzeError(iErr, "# error at SetFilePointer: ");
        }
        return bRetValue;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Читать один сектор с жесткого диска
void* RawRead(PHARDINFO inf)
{
        UINT iErr, SectorSize, nRead, i, n;
        void* buf;
       
        SectorSize = inf->dwSectorSize;
       
        if(!SectorSize)SectorSize = 0x200;
       
        buf = malloc(SectorSize);
        while(!ReadFile(inf->hDrive, buf, SectorSize, &nRead, NULL))
        {
                iErr=GetLastError();
                free(buf);
                if((iErr == ERROR_INVALID_PARAMETER)&&(SectorSize<0x8000))
                {
                        SectorSize = SectorSize*2;
                        buf = malloc(SectorSize);
                        continue;
                }
                AnalyzeError(iErr, "# error at ReadFile: ");
                return NULL;
        };
        if(inf->dwSectorSize != SectorSize)
        {
                i = SectorSize; n = 0;
                while(i = i/2)n++;
                inf->bitsPerSector = n;
                inf->dwSectorSize = SectorSize;
        }
       
        return buf;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*Изъять серийный номер для FAT или NTFS
        abs_addr        - адрес начала логического диска в секторах
        Serial        - адрес 8-байтного буфера для серийного номера
        id                - идентификатор файловой системы
*/
BOOL GetDiscSerial(PHARDINFO inf, UINT abs_addr, UCHAR* Serial, UCHAR id)
{
        char* buf;
        int i;
       
        if(MovePointer(inf, abs_addr) == -1)return FALSE;
        if((buf = RawRead(inf)) == NULL)return FALSE;
       
        switch(id)
        {
                case 0x07:                        //NTFS
                memcpy(Serial,buf+72,8);       
                break;
               
                case 0x0E:
                case 0x0C:
                case 0x0B:                        //FAT32
                memcpy(Serial,buf+67,4);
                break;
       
                default:
                for(i=0; i<sizeof(FAT); i++)
                        if(id == FAT[i])
                        {
                                memcpy(Serial, buf+39, 4);
                                free(buf);
                                return TRUE;
                        }
                return FALSE;
        }
        free(buf);
        return TRUE;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
PHARDINFO Init(char n)
{
        char HardDiskName[] = "\\\\.\\PHYSICALDRIVE0";
        void* hDrive;
        UINT iErr, dwSectorSize;
        PHARDINFO inf;
       
        HardDiskName[sizeof(HardDiskName)-2] = n+'0';

        hDrive = CreateFile(
                HardDiskName,
                GENERIC_READ,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL, OPEN_EXISTING, 0, NULL
              );

        if(hDrive == INVALID_HANDLE_VALUE)
        {
                iErr = GetLastError();
                if(iErr == ERROR_FILE_NOT_FOUND)return NULL;
                AnalyzeError(iErr, "# Error at CreateFile: ");
                return NULL;
        }
       
        inf = malloc(sizeof(HARDINFO));
        inf->hDrive = hDrive;
        inf->nHard = n;
        inf->dwSectorSize = 0;

        return inf;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void DeInit(PHARDINFO inf)
{
        CloseHandle(inf->hDrive);
        free(inf);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Вывести список разделов из Partition Table в MBR
UINT ListMBR(PHARDINFO inf, UCHAR* pMBR, UINT dwMBRAddr)
{
        UCHAR* pPart;
        UCHAR id, active;
        UINT ext = 0, secBegin, secLength, mbLength=0, gbLength=0;
        UINT SectorSize, abs_addr, SN4;
        UCHAR SN[8];
        char* cpFS;
        int i;
       
        SectorSize = inf->dwSectorSize;
        pPart = pMBR+0x01BE;
       
        for(i=0; i<4; i++)
        {
                id = pPart[4];
                if(!id)
                {
                        pPart += 0x10;
                        continue;
                }
                secBegin = *(UINT*)&pPart[8];
                secLength = *(UINT*)&pPart[12];
                active = pPart[0];
                if(active)active = '+';
                else active = '-';
                pPart += 0x10;
                mbLength = secLength/(2*1024)*SectorSize/512;
                gbLength = mbLength/1024;
                abs_addr = dwMBRAddr + secBegin;
               
                cpFS = GetFileSystem(id);
               
                if((id == 0x0F)||(id == 0x05))
                {
                        ext=secBegin;
                        continue;
                }
                memset(SN, 0,sizeof(SN));
                GetDiscSerial(inf, abs_addr, SN, id);
                memcpy(&SN4, SN, 4);
       
                printf("HDD%c  %c:    %c    %08X    %08X    (%02X)%s    %08X    %u %s\n",
                  '0'+inf->nHard,
                  SN4?GetDiscBySN(SN4):'?',
                  active,
                  abs_addr, secLength, id, cpFS,
                  SN4,
                  gbLength?gbLength:mbLength,
                  gbLength?"GB":"MB"
                );
                GetDiscBySN(SN4);
        }
        return ext;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Печатать заголовок
void PrintHead()
{
        printf("# MBR reader starts\n");
        printf("HDD  Disc  Boot  Addr        Size        FS            SN          mb/gb\n");
        printf("------------------------------------------------------------------------\n");
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Проверить сигнатуру
BOOL CheckMBR(UCHAR* pMBR)
{
        BOOL bRetValue=*(USHORT*)(pMBR+0x01FE)==0xAA55;
        if(!bRetValue)printf("# invalid MBR\n");
        return bRetValue;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Пройтись по цепочке MBR
BOOL WalkOnMBR(PHARDINFO inf)
{
        UINT ext, dwNextMBRAddr;
        void* pMBR;
       
        if((pMBR = RawRead(inf)) == NULL)return FALSE;
        if(!CheckMBR(pMBR))
        {
                free(pMBR);
                return FALSE;
        }
        if(ext = ListMBR(inf,pMBR,0))
        {
                inf->dwExtendedAddr = ext;
                ext=0;
                while(1)
                {
                        free(pMBR);
                        dwNextMBRAddr = ext + inf->dwExtendedAddr;
                        if(MovePointer(inf, dwNextMBRAddr) == -1)return FALSE;
                        if((pMBR = RawRead(inf)) == NULL)return FALSE;
                        if(!CheckMBR(pMBR))
                        {
                                free(pMBR);
                                return FALSE;
                        }
                        if(!(ext = ListMBR(inf, pMBR, dwNextMBRAddr)))break;
                }
        }
        free(pMBR);
        return TRUE;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//Точка входа
int main(int argc, char** argv)
{
        PHARDINFO inf;
        UCHAR nHDD = 0;
               
        PrintHead();
        while(inf = Init(nHDD))
        {
                WalkOnMBR(inf);
                DeInit(inf);
                nHDD++;
        }
}

http://slil.ru/26470215
De-v: вещь полезная прикреплю файлы к посту)

criz 22.12.2008 22:46

Полезные вещи :) спасибо за сорцы)

Delimiter 22.12.2008 23:33

маладец! 8)) ...

только лучше в министатьи!

De-visible 22.12.2008 23:42

ТС, повторюсь, очень даже не плохо))), вообщем если согласен, то офрми красивенько и запости в министатьи))
---
p.s. Delimiter приведддд)))

Delimiter 22.12.2008 23:43

да да ... оформи тока!!! 8))
________________________________
De-visible привед!!!

bons 23.12.2008 01:23

полагаю, что статья, даже мини, должна чему-то учить, в статье должен быть какой-то материал для развития. А здесь просто исходники.
Запостил ссылку сюда в теме "Полезные программы[С/С++, C#, Delphi, .NET, Asm]" .

slesh 23.12.2008 16:45

В принципе полезно, в особенности mbr. Ping - можно и более проще реализовать )

p.s. IcmpCloseHandle - под NT видными лучше не использовать. Ошибку в программе часто выдает.

ss88 23.12.2008 17:13

2bons ты бы сигнатур файловых систем для наглядности добавил бы, а то только 4 штуки ;)

bons 23.12.2008 17:46

Цитата:

Сообщение от slesh
IcmpCloseHandle - под NT видными лучше не использовать. Ошибку в программе часто выдает.

в какой-то статье видел подобную информацию, но...
тестировал на WinXP SP2 и SP3 ошибки не было, все в порядке. В MSDN тоже ничего не сказано.. Если действительно проблема актуальна то код изменю..

Цитата:

Сообщение от ss88
2bons ты бы сигнатур файловых систем для наглядности добавил бы, а то только 4 штуки

Там проверка на 5 самых распространенных ФС. Можно было бы и больше распознавать но я не нашел точный полный список кодов файловых систем

slesh 24.12.2008 00:56

На зчет закрытия дескриптора - то возможно си проверяет данные исключения автоматом. А вот проги на делфье порой вылетают и на XP SP2 и на W2K3


Время: 04:41