首页
社区
课程
招聘
[原创]笑解 API 函数 -- API 绝密档案系列之一
发表于: 2006-3-1 07:14 114322

[原创]笑解 API 函数 -- API 绝密档案系列之一

2006-3-1 07:14
114322

看到 qduwg 老师凭"【翻译】3个脱壳相关的重要函数介绍" 也"骗"到一个精,不觉心痒,也弄几个函数来介绍一下,不过我不是翻译,而是著作。我们就从 qduwg 老师介绍的几个函数入手。希望上面的话没有伤到 qduwg 老师的自尊心。我看到你对别人评价的反应,知道你很在意这些。

1. HMODULE GetModuleHandle(
  LPCTSTR lpModuleName   // address of module name to return handle
                         // for
);

  GetModuleHandle 实际上分为两个函数
  
  GetModuleHandleA--处理 Ansi 字符串
  GetModuleHandleW--处理 Unicode 字符串
  
其实真正干活的函数是,GetModuleHandleW (指NT以后的系统),GetModuleHandleA 只不过将用户输入的 Ansi 字符串转成 Unicode 字符串然后就直接调用 GetModuleHandleW,所以在 OD 中如果下断拦截这个函数,直接拦截 GetModuleHandleW 就可以了,保险一个都跑不掉。我看一些新手写 Hook 程序时往往不厌其烦的将每个函数都“沟”一下,其实大可不必,随着我的文章深入,你会发现一个基本原则--千条江河归大海,大部分的调用其实最后都是进入最底层的 ntoskrnl.exe、Hal.dll、和其他几个内核程序。而我们平常打交道最多的 Kernel32.dll 和 ntdll.dll 其实只是对底层函数进行了包装(当然对于某些ring3层的特定功能还是自己完成的),相当于一个接口,起一个中转和隔离的作用,将用户的函数调用进行预处理,比如检测用户参数的合法性,对用户参数进行重新排序(底层函数的参数排列顺序有时和用户层不同,这样可以防止你轻易的弄明白底层在干什么),将用户的调用分离拆解为若干个更为细小的调用,因为底层函数分类往往更细,这样比较灵活。
使用 GetModuleHandle 函数,在高级语言中可以直接写成:
hMod = GetModuleHandle(lpModuleName);
编译器会根据参数的性质自行决定调用那一个函数,但在汇编中却不能这样使用,你必须明确的指明你要使用那一个函数。另外在OD中下断点,你也必须明确的指明对那一个函数下断,例如在OD中,进入CPU窗口,按Ctrl-G,然后输入GetModuleHandle,OD会告诉你 “未识的标识符”,你必须清楚的告诉 OD 你到底要在那一个函数下断,是 A 还是 W。按前面的说法其实你只要下 GetModuleHandleW 就可以了(当然有时候在A下断,比较容易知道程序是从那里调用的,如果程序使用的是A调用)。

俗话说,口说无凭。你怎么知道那两个还是最后变成了一个?
看雪老大也在qduwg的文章后说:

77E80B1A ; HMODULE __stdcall GetModuleHandleA(LPCSTR lpModuleName)
77E80B1A           public GetModuleHandleA
77E80B1A GetModuleHandleA proc near              ; CODE XREF: sub_77E684C2+2p
77E80B1A                                         ; CreateRemoteThread+FBp ...
77E80B1A
77E80B1A lpModuleName= dword ptr  8
77E80B1A
77E80B1A           push  ebp
77E80B1B           mov   ebp, esp
77E80B1D           cmp   [ebp+lpModuleName], 0
77E80B21           jnz   short loc_77E80B31      ; lpModuleName 是有效的则转移
77E80B23           mov   eax, large fs:18h       ; TEB.NT_TIB.Self
77E80B29           mov   eax, [eax+30h]          ; TEB.Peb
77E80B2C           mov   eax, [eax+8]            ; PEB.ImageBaseAddress
77E80B2F           jmp   short loc_77E80B45
77E80B31
77E80B31 loc_77E80B31:                           ; CODE XREF: GetModuleHandleA+7j
77E80B31           push  [ebp+lpModuleName]
77E80B34           call  @AnsiStrToUnicodeStr    ; 将Ansi字符串转成Unicode字符串
77E80B39           test  eax, eax
77E80B3B           jz    short loc_77E80B45
77E80B3D           push  dword ptr [eax+4]       ; lpModuleName
77E80B40           call  GetModuleHandleW        ; 这里开始同流合污了。
77E80B45
77E80B45 loc_77E80B45:                           ; CODE XREF: GetModuleHandleA+15j
77E80B45                                         ; GetModuleHandleA+21j
77E80B45           pop   ebp
77E80B46           retn  4
77E80B46 GetModuleHandleA endp
kd> !teb                 //老盖的Debug命令一般都需要这个"哇"符号做前缀,读作"哇!!添一杯"
TEB at 7FFDE000
    ExceptionList:    12f830                \   0x0
    Stack Base:       130000                |   0x4
    Stack Limit:      126000                |   0x8
    SubSystemTib:     0                     |   0xC     这里其实是 NT_TIB 的一个结构
    FiberData:        1e00                  |   0x10
    ArbitraryUser:    0                     |   0x14
    Self:             7ffde000              /   0x18
    EnvironmentPtr:   0                         0x1C
    ClientId:         4cc.4c8                   0x20
    Real ClientId:    4cc.4c8                   0x24
    RpcHandle:        0                         0x28
    Tls Storage:      0                         0x2C
    PEB Address:      7ffdf000                  0x30  这里指向 PEB 表,即进程环境块
    LastErrorValue:   0
    LastStatusValue:  8000001a
    Count Owned Locks:0
    HardErrorsMode:   0
kd> !kdex2x86.strct peb  //如果 kdex2x86 已经加载,可以直接输入 !strct peb
struct   _PEB (sizeof=488)
+000 byte     InheritedAddressSpace
+001 byte     ReadImageFileExecOptions
+002 byte     BeingDebugged                   //Debug运行标志
+003 byte     SpareBool
+004 void     *Mutant
+008 void     *ImageBaseAddress               //这里就是程序加载的基地址了
+00c struct   _PEB_LDR_DATA *Ldr
+010 struct   _RTL_USER_PROCESS_PARAMETERS *ProcessParameters
+014 void     *SubSystemData
+018 void     *ProcessHeap
+01c void     *FastPebLock
+020 void     *FastPebLockRoutine
+024 void     *FastPebUnlockRoutine
+028 uint32   EnvironmentUpdateCount
+02c void     *KernelCallbackTable
+030 uint32   SystemReserved[2]
+038 struct   _PEB_FREE_BLOCK *FreeList
+03c uint32   TlsExpansionCounter
+040 void     *TlsBitmap
+044 uint32   TlsBitmapBits[2]
+04c void     *ReadOnlySharedMemoryBase
+050 void     *ReadOnlySharedMemoryHeap
+054 void     **ReadOnlyStaticServerData
+058 void     *AnsiCodePageData
+05c void     *OemCodePageData
+060 void     *UnicodeCaseTableData
+064 uint32   NumberOfProcessors
+068 uint32   NtGlobalFlag
+070 union    _LARGE_INTEGER CriticalSectionTimeout
+070    uint32   LowPart
+074    int32    HighPart
+070    struct   __unnamed3 u
+070       uint32   LowPart
+074       int32    HighPart
+070    int64    QuadPart
+078 uint32   HeapSegmentReserve
+07c uint32   HeapSegmentCommit
+080 uint32   HeapDeCommitTotalFreeThreshold
+084 uint32   HeapDeCommitFreeBlockThreshold
+088 uint32   NumberOfHeaps
+08c uint32   MaximumNumberOfHeaps
+090 void     **ProcessHeaps
+094 void     *GdiSharedHandleTable
+098 void     *ProcessStarterHelper
+09c uint32   GdiDCAttributeList
+0a0 void     *LoaderLock
+0a4 uint32   OSMajorVersion
+0a8 uint32   OSMinorVersion
+0ac uint16   OSBuildNumber
+0ae uint16   OSCSDVersion
+0b0 uint32   OSPlatformId
+0b4 uint32   ImageSubsystem
+0b8 uint32   ImageSubsystemMajorVersion
+0bc uint32   ImageSubsystemMinorVersion
+0c0 uint32   ImageProcessAffinityMask
+0c4 uint32   GdiHandleBuffer[34]
+14c function *PostProcessInitRoutine
+150 void     *TlsExpansionBitmap
+154 uint32   TlsExpansionBitmapBits[32]
+1d4 uint32   SessionId
+1d8 void     *AppCompatInfo
+1dc struct   _UNICODE_STRING CSDVersion
+1dc    uint16   Length
+1de    uint16   MaximumLength
+1e0    uint16   *Buffer
77E80B1A           push  ebp
77E80B1B           mov   ebp, esp
77E80B1D           cmp   [ebp+lpModuleName], 0
77E80B21           jnz   short loc_77E80B31      ; lpModuleName 是有效的则转移
77E80B23           mov   eax, large fs:18h       ; TEB.NT_TIB.Self
77E80B29           mov   eax, [eax+30h]          ; TEB.Peb
77E80B2C           mov   eax, [eax+8]            ; PEB.ImageBaseAddress
77E80B2F           jmp   short loc_77E80B45
77E80B23           mov   eax, large fs:18h       ; TEB.NT_TIB.Self

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (83)
雪    币: 146
活跃值: (72)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
 支持加精了~
2006-3-1 07:39
0
雪    币: 242
活跃值: (135)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
讲的都是很严肃的问题,
2006-3-1 08:17
0
雪    币: 50161
活跃值: (20660)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
讲解过程中,gzgzlxg很懂得转一个话题,轻松一下气氛,使得枯燥的内容有趣味,学习
2006-3-1 09:13
0
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
5
果真是笑解,呵呵~
2006-3-1 09:18
0
雪    币: 333
活跃值: (40)
能力值: ( LV9,RANK:730 )
在线值:
发帖
回帖
粉丝
6
好文,学习。
2006-3-1 10:02
0
雪    币: 7271
活跃值: (3905)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
asd
7
学习
2006-3-1 10:16
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
8
支持~接着来
2006-3-1 11:45
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
9
谢谢,谢谢 (注意这些谢谢要用广东话发音,否则就没有味道了,哈哈,如果是北方人学广东话发音,那就更妙,一般读着 ”jiejie","jiejie",听到了没有,那是“姐姐,姐姐”)
为骗“精”成功而庆祝,那当然离不开 “可爱的水”。
2006-3-1 12:00
0
雪    币: 1334
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
哈哈,将我买帆船游艇的秘密也泄露了, 到时候我在船上摆下 “鸿门宴”, 找一个长得像"章子怡"那样的"樊哙",来跳“十面埋伏”里的那种袖子舞; 哈哈
2006-3-1 12:44
0
雪    币: 1334
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
看看还没看到 女樊哙,就开始学叫 “jiejie”了,哈哈
古来圣贤皆寂寞,唯有饮者留其名
2006-3-1 12:47
0
雪    币: 267
活跃值: (235)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
12
写得不错啊,支持!
2006-3-1 14:20
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
模拟函数我这里有一套。不就那个老外的杰作嘛,原来他老人家没名没姓
2006-3-1 14:39
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
14
蛋壳兄,能不能发来学习学习?
另外这里有个鸡蛋壳,还有个鹅蛋壳,你们是什么关系?
2006-3-1 14:48
0
雪    币: 671
活跃值: (723)
能力值: ( LV9,RANK:1060 )
在线值:
发帖
回帖
粉丝
15
学习了,另外我也引用一下:

最初由 gzgzlxg 发布
注:修改了一些错笔字,........


2006-3-1 15:00
0
雪    币: 234
活跃值: (370)
能力值: ( LV9,RANK:530 )
在线值:
发帖
回帖
粉丝
16
好文章,学习
2006-3-1 15:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
不错,学习了.
2006-3-1 17:36
0
雪    币: 222
活跃值: (40)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
18
强贴留名
2006-3-1 19:17
0
雪    币: 210
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
学习了 !支持!
2006-3-2 10:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
最初由 周二两 发布
学习了 !支持!
2006-3-2 21:31
0
雪    币: 214
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
21
严重学习!
2006-3-3 17:14
0
雪    币: 2506
活跃值: (1030)
能力值: (RANK:990 )
在线值:
发帖
回帖
粉丝
22
好文章!生动有趣,确是笑解
2006-3-3 18:01
0
雪    币: 21
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
顶!顶!顶!
2006-3-3 19:30
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
24
谢谢 CCDebuger,希望大家多给点鼓励,关于底层的文章并不好写,没有地方去查找这些资料,所以都要经过仔细的分析,思考才能下笔。论坛许多朋友基础不是很好,怎么写,对我也是需要考虑的因数,前几天发的 【IDA -- idc delphi 类表的建立】,应该属于999999(六九)赤金级的文章(那个香港的周大幅卖的是9999金),但并没有人欣赏,对于这个系列,存在同样的问题,写的多了深了,没有人看,吃力不讨好,写的少了,潜了,含金量下降,真的不知怎样才能符合大家的胃口。有道是:蜀道难,难于上青天。
2006-3-5 06:34
0
雪    币: 342
活跃值: (318)
能力值: ( LV12,RANK:740 )
在线值:
发帖
回帖
粉丝
25
最初由 gzgzlxg 发布
谢谢 CCDebuger,希望大家多给点鼓励,关于底层的文章并不好写,没有地方去查找这些资料,所以都要经过仔细的分析,思考才能下笔。论坛许多朋友基础不是很好,怎么写,对我也是需要考虑的因数,前几天发的 【IDA -- idc delphi 类表的建立】...真的不知怎样才能符合大家的胃口。有道是:蜀道难,难于上青天。


写底层的文章难,难于上蜀道。
2006-3-5 08:32
0
游客
登录 | 注册 方可回帖
返回
//