Archive for 十二月, 2009

FS寄存器,关于前一篇中获得当前PEB的一些疑点

星期四, 十二月 17th, 2009

FS寄存器指向当前活动线程的TEB结构(线程结构)

偏移 说明
000 指向SEH链指针
004 线程堆栈顶部
008 线程堆栈底部
00C SubSystemTib
010 FiberData
014 ArbitraryUserPointer
018 FS段寄存器在内存中的镜像地址
020 进程PID
024 线程ID
02C 指向线程局部存储指针
030 PEB结构地址(进程结构)
034 上个错误号

得到KERNEL32.DLL基址的方法


(全文…)

kernel32里的 GetVersion 函数的逆向分析

星期一, 十二月 14th, 2009

今天在家调试程序,跟进了一个函数kernel32里面的GetVersion函数。最近刚好在学逆向。心一横,干脆把它逆了。

代码如下:

0043846A  |.  FF15 70F14500 call    dword ptr [<&KERNEL32.GetVersion>]                ;  kernel32.GetVersion

7C81126A >  64:A1 18000000       mov     eax, dword ptr fs:[18]         ; 获得当前线程的TEB地址
7C811270    8B48 30                       mov     ecx, dword ptr [eax+30]        ; 在TEB偏移30h处获得PEB地址
7C811273    8B81 B0000000        mov     eax, dword ptr [ecx+B0]
7C811279    0FB791 AC000000   movzx   edx, word ptr [ecx+AC]
7C811280    83F0 FE                       xor     eax, FFFFFFFE
7C811283    C1E0 0E                      shl     eax, 0E
7C811286    0BC2                            or      eax, edx
7C811288    C1E0 08                      shl     eax, 8
7C81128B    0B81 A8000000        or      eax, dword ptr [ecx+A8]
7C811291    C1E0 08         shl       eax, 8
7C811294    0B81 A4000000        or      eax, dword ptr [ecx+A4]
7C81129A    C3                                retn
解析:

哈哈,阳光总在风雨后

星期天, 十二月 13th, 2009

呵呵,生活终归还是美好的。

虽然造物弄人,但只要坚持,一般结果都还是好的。

我也比较服我自己。

我们又在一起了。

搂着自己很爱的女孩是一种幸福。

 

【天书笔记】C函数传参过程

星期天, 十二月 13th, 2009

一.C函数调用与堆栈的关系

C语言通过堆栈将参数传入函数内部

push和pop的时候esp用于指向栈顶——栈顶总是栈中地址最小的位置。push则esp减少,pop则esp增加。

二.函数调用规则

定义:函数调用规则是指调用者和被调用函数之间传递参数及返回参数的方法。

Windows上常用的有Pascal方式,WINAPI(_stdcall)方式以及C方式(_cdecl)。

1._cdecl方式

参数入栈:参数从右到左依次入栈

清理方式:函数返回后,调用者负责清理堆栈。这种调用会生成较大的可执行程序。

2._stdcall方式(WINAPI方式)

参数入栈:参数从右到左依次入栈

清理方式:被调用函数在返回前自行清理堆栈。生成代码比_cdecl方式小。

3.Pascal方式

入栈方式:参数从左到右依次入栈

清理方式:被调用函数在返回前自行清理堆栈

不支持可变参数的函数调用

此外Windows内核中还有常见的_fastcall快速调用;c++中有_thiscall方式。

任何调用方式,最终返回值都是写入eax,然后返回。外部从eax中取得返回值。 (全文…)

或许我就不该这么做,我想骂人,但不想骂你

星期三, 十二月 9th, 2009

 /////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

我受不了了

杯具

一切都用C++注释的方式来表示吧

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

你走了,这里剩下我一人。

我要去外面疯一圈

/////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////

我就不该容许自己有爱情。。。。。。。。。

 

 

这一刻,我告别了单身

星期一, 十二月 7th, 2009

好多年没有这样喜欢一个女孩,真的。

今天我们告别了单身,以至于我不知道改以怎样的方式来证实这一刻。

和一个自己喜欢的女孩在一起,这样的故事在我身上已经5年没有发生过了。

希望我的博客帮我记住这一刻。

希望我和她能走得远一些。

希望!!!


谢谢织织。

另外谢谢樊爽,李菲。。。。。

选择或者抉择

星期六, 十二月 5th, 2009

 我已承受不起失败,3岁不是很大的差别,但如果你不理解,或者你并不在意这一切,那么我的付出就是没有意义的。

生理决定心理,心理决定行为。我无意中说出了这么一句,或许她真的对我是有影响的。

我已无法不顾一切的付出,我必须核算我的付出风险。

我从你那里没有得到一丝丝信号,连个毛也没有。

我不得不重新考虑我该怎么做。我必须给自己留以余地。

理智必须压倒一切,虽然这很难。

我宁可不看你一眼,扭头落泪,继而狂奔。也不能葬送了我自己。

88,我要做我自己。自己的失败才是真的失败。

如果有一天你发现我,请你不要惊讶我这么快就做了决定。

要知道,作决定是很痛苦的,我也不例外。


我多么希望能和你一起看那轮圆圆的月亮从东方升起,晚霞照耀着西边“巨乳峰”。

我多么希望能和你一起周末走进影院,哪怕反复看那部《2012》。

我多么希望能和你一起在厨房做一些小东西吃,哪怕它并不好吃。


只要我喜欢,一切都可以。


也许有一天你会抱怨我的沉默。

也许有一天我们还会再遇见。

当然,也许你没有觉得什么不同。


在程序的世界里,没有织女。

我擅自闯入尘世,寻找千百度,可你却不属于人间。

也许上天注定不会有结果。


为自己惋惜。。。。。。

而我只能在这个真正属于我的小角落里记录下这一时刻。


我仍会为你付出

因为我的感觉还在

我只是不能不计风险

我多么希望你能够注意到我的一切

我多么希望你能融入我的世界


可是一切随缘吧

地上牛郎天上星

天上之女地上锦

接下来交给缘分吧

 

原来我的心还活着

星期六, 十二月 5th, 2009

        我越发的离不开你,看见你我就会很高兴,和你发短信我都会很踏实,和你做任何事,哪怕是逛街,我都情绪高涨。

        已经好多年没有遇到能让我有这种感觉的女孩了。我发自内心的高兴,既为了我遇见你,也为了我的心原来还活着。我不知道是不是在电影院里你激活了我,在或者第一次见面就真的为后面的情节埋下了伏笔。爱就是害怕失去,害怕失去现有的一切,我在自己身上找到了这种东西,我有些不敢和你说,我怕失去。我承受不起。

        你的眼神,你柔软的语调,你那老成的造型和小孩的言语之间的差异,没有一样不吸引着我。我真的掉进去了。谢谢你给我带来的一切,也许你并没有在意,但我很感激。

敏感很痛苦,敏感的人要看似不敏感那无疑更痛苦

星期五, 十二月 4th, 2009

    一颗敏感的心就像一个高精度传感器,能感知许多变化。

    

    处理这些变化很痛苦。要处理这些变化而不让别人知晓自己捕获到了这些变化,则无疑是更痛苦的。

    

    我已经很久没有捕获到这中变化了,但捕获到了又有什么用,我依然处理不了。

    

    我仅仅是我而已,能做的很有限,希望你能明白。

用LIST_ENTRY双向链表实现文件操作的监控 ,写于08年

星期五, 十二月 4th, 2009

 这两个星期天天都在搞这个,无数个错误被修正过后,做些笔记以备以后查阅。

        为了实现机密文档的保护,文档管理系统必须对所有打开的文件进行监控,因此我们的过滤驱动需要知道当前运行时刻有几个文件被打开,它们分别被打开了几次(同一个文件可能被多次打开)。

            用户态和内核态之间的关系

                         用户态调用CreateFile函数,子系统将请求发给IO管理器,IO管理器会用该函数的

                 参数生成一个IRP,将此IRP发往底层。过滤驱动截获到IRP,开始对其操作。过滤驱动

                 操作完了之后会继续往下发,就是调用更下层驱动程序。当下层所有操作完成之后,底

                 层的完成信息会向上反。这有点像函数的嵌套调用,从最内层函数开始一级一级的返回,

                 但这只是像。下面是过滤驱动截获返回的CreateFile时的操作。

处理IRP_MJ_CREATE的核心代码():

         {
    //返回的FsContext为空时,不予以处理
    if(FileObject->FsContext == NULL)
    {
     ////////////////////////////////////////DbgPrint("\n\n\n SfCreate: FileObject->FsContext 为 NULL\n\n\n");
     status = Irp->IoStatus.Status;

     DbgPrint("\n SfCreate() : 建立链表的第一个节点时遭遇 FsContext 为 NULL   \n",status);

     IoCompleteRequest( Irp, IO_NO_INCREMENT );
     return status;
    }

      //第一次打开链表时,链表为空,上面for语句无法运行

    if(IsListEmpty(&my_list_head))
    {
     PFILE_CONTEXT FileCtx = (PFILE_CONTEXT)ExAllocatePoolWithTag(PagedPool,sizeof(FILE_CONTEXT),SFLT_POOL_TAG);
     if(FileCtx == NULL)
      return STATUS_INSUFFICIENT_RESOURCES;

     FileCtx->FsContext = FileObject->FsContext;
     FileCtx->RefCount = 1;

     ExInterlockedInsertTailList(&my_list_head,&FileCtx->ListEntry,&my_list_lock);//多线程安全插入方式

     DbgPrint("\n\n SfCreate() : 创建链表的第一个节点:\n ");
     DbgPrint("SfCreate() : 第一个节点中 FileCtx->FsContext: %x , FileCtx->RefCount: %u \n\n\n",FileCtx->FsContext,FileCtx->RefCount);

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

    //搜索链表,查看文件是否已经打开(链表非空时,此搜索才可以进行)
    for(p=my_list_head.Flink; p!=&my_list_head; p=p->Flink)
    {
     PFILE_CONTEXT Elem = CONTAINING_RECORD(p,FILE_CONTEXT,ListEntry);

     //文件已打开,计数器加一
     if(Elem->FsContext == FileObject->FsContext)
     {
      KIRQL irql;
     
      DbgPrint("\n\n\nSfCreate() : 遇到已打开过的文件 , 打印Elem节点信息如下 :\n ListEntry: %s, FsContext: %x, RefCount: %u\n",Elem->ListEntry,Elem->FsContext,Elem->RefCount);

      if( FileObject->FsContext == NULL)
       DbgPrint( "SfCreate() : FileObject->FsContext 为 空");

      KeAcquireSpinLock(&my_list_lock,&irql);          
      Elem->RefCount += 1;    
      KeReleaseSpinLock(&my_list_lock,irql);

      ////////////////////////////////////////DbgPrint("\n文件第 %u 次打开\n",Elem->RefCount);

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


    //文件未打开,填充节点并插入链表

    { 
     //节点内存分配
     PFILE_CONTEXT FileCtx = (PFILE_CONTEXT)ExAllocatePoolWithTag(PagedPool,sizeof(FILE_CONTEXT),SFLT_POOL_TAG);
     if(FileCtx == NULL)
     {
      DbgPrint("\n\n SfCreate() : 文件第一次打开时,内存分配失败");
      return STATUS_INSUFFICIENT_RESOURCES;
     }

     //节点内容填充
     FileCtx->FsContext = FileObject->FsContext;
     FileCtx->RefCount = 1;

     //插入节点到链表
     ExInterlockedInsertTailList(&my_list_head,&FileCtx->ListEntry,&my_list_lock);//多线程安全插入方式
    }
   }      

大体思路说明:

        获取文件对象,确认它是对一个文件的操作(不是就就忽略,直接返回)。然后获取其FsContext,这是文件的全局唯一标识,一个文件不管打开多少次,它只有一个FsContext,不同文件的FsContext也不一样。如果链表为空,直接用这个FsContext填充数据结构,创立一个节点,然后插入链表,之后返回。如果链表不为空,则遍历搜索链表,如果查找到FsContext值一样的节点则说明该文件打开过,只需将该节点数据结构中的RefCount++。如果链表中没有搜索到相应节点,那么就要新建一个节点插入链表。

         既然监控就不能只监控打开的,自然也要监控关闭的。

         当关闭一个文件窗口的时候,IO管理器会发送一个IRP_MJ_CLEANUP。在处理这个消息的时候,我们需要做的仅仅是从链表中找到那个文件,将其RefCount–。当RefCount值为0的时候,IO管理器就会发送一个IRP_MJ_CLOSE,截获到这个消息,我们就可以将这个文件对应的节点从链表中删除了。

        OK!That’s all.

关键用法

    A.链表的遍历搜索

                   if(IsListEmpty(&my_list_head))       {    插入第一个节点 返回     }

                   for(p=my_list_head.Flink; p!=&my_list_head; p=p->Flink)    

                  从循环体内推出说明没找到,这就需要我们新建节点了

 

                  关键是要优先处理空链表的情况

    B.链表的插入删除操作

                      ExInterlockedInsertTailList(&my_list_head,&FileCtx->ListEntry,&my_list_lock);

                      删除LST_ENTRY p所指向的节点,第一个参数需要用前一个节点的LIST_ENTRY

                       ExInterlockedRemoveHeadList(p->Blink,&my_list_lock);

    C.IRQL锁与互斥体

                     KeAcquireSpinLock(&my_list_lock,&Irql);
                     Elem->RefCount -= 1;
                     KeReleaseSpinLock(&my_list_lock,Irql);

                     它通过提高IRQL来使其他线程无法执行,解决同步问题

                       ExAcquireFastMutex( &gSfilterAttachLock );                                       

                      ExReleaseFastMutex( &gSfilterAttachLock );

                      这个要相对轻量级

վ:Ħ Ϻgay ŰĦ Ϻ տ ɽ ɽ ŰĦ Ϻ˹˾ ŰĦ ϺŰĦ ˹˾ ݰĦ ŰĦ Ħ ϺĦ ͬ־ Ѽ˹˾ ŰĦ ϺѼ ɳ᳡ shenzhen massage ŰĦ ͬ־ Ϸʿյά ϲŰĦ 人˿ఴĦ ɽ˹˾ Ϻ Ѽ˿ Ħ ֣ŰĦ ˹˾ ݼѼ Ϻ ǿ Ϻ ڰ᳡۸ °˾
ӣǵɽǵݸǵ麣ǵɽǵɳǵɽǵǵǵǵϺǵǵǵǵݸǵɽǵ麣ǵǵɽǵɽǵǵǵǵǵǵǵǵϺǵŰĦϺǵɽanĦൺǵӰװϷϺǵϾŰĦϾŰĦϾŰĦ㶫huλ㽭huңhuң
ӣҸĻȾ,ɾӹȫ.
ugg boots cheap UGG Boots UGG Boots Sale UGG Bailey Button Triplet ugg australia uk mens ugg boots new ghd hair straighteners coach handbags outlet
ӣվĶ٣ÿ쿴ɾ, ұ˫Ϊ˴Ǯ;ãӲҪɾҾɾվɾipҲ㡣
ɹͷ Ҹ θ Ƽʪõķ ҸƷ ƾõҽԺ 򾲶ʮζ ƹɹͷҩ θҩ ҽԺ ɹͷô ƹɹͷõҽԺ θҽԺ ̿۸ lovegreen californianews
ӣǵάɽǵάݸǵά麣ǵάɽǵάɳǵάɽǵάǵάǵάǵάϺǵάǵάǵάǵάݸǵάɽǵά麣ǵάǵάɽǵάɽǵάǵάǵάǵάǵάǵάǵάǵάϺװ˿㰴ĦϺǵάɽСlaohujiϷǵӰװϾСϾСϾС㽭huϷɽǵά˿㰴Ħ