PEB及LDR链
PEB地址的取得
在NT内核系统中fs寄存器指向TEB结构,TEB+0x30处指向PEB结构,PEB+0x0c处指向PEB_LDR_DATA结构,PEB_LDR_DATA+0x1c处存放一些指向动态链接库信息的链表地址,win7下第一个指向ntdl.dll,第三个就是kernel32.dll的。
typedef struct _TEB
{
    NT_TIB Tib;                             /* 00h */
    PVOID EnvironmentPointer;               /* 1Ch */
    CLIENT_ID Cid;                          /* 20h */
    PVOID ActiveRpcHandle;                  /* 28h */
    PVOID ThreadLocalStoragePointer;        /* 2Ch */
    struct _PEB *ProcessEnvironmentBlock;   /* 30h */
    ULONG LastErrorValue;                   /* 34h */
    ULONG CountOfOwnedCriticalSections;     /* 38h */
    PVOID CsrClientThread;                  /* 3Ch */
    struct _W32THREAD* Win32ThreadInfo;     /* 40h */
    ULONG User32Reserved[0x1A];             /* 44h */
    ULONG UserReserved[5];                  /* ACh */
    PVOID WOW32Reserved;                    /* C0h */
    LCID CurrentLocale;                     /* C4h */
    ULONG FpSoftwareStatusRegister;         /* C8h */
    PVOID SystemReserved1[0x36];            /* CCh */
    LONG ExceptionCode;                     /* 1A4h */
    struct _ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; /* 1A8h */
    UCHAR SpareBytes1[0x28];                /* 1ACh */
    GDI_TEB_BATCH GdiTebBatch;              /* 1D4h */
    CLIENT_ID RealClientId;                 /* 6B4h */
    PVOID GdiCachedProcessHandle;           /* 6BCh */
    ULONG GdiClientPID;                     /* 6C0h */
    ULONG GdiClientTID;                     /* 6C4h */
    PVOID GdiThreadLocalInfo;               /* 6C8h */
    ULONG Win32ClientInfo[62];              /* 6CCh */
    PVOID glDispatchTable[0xE9];            /* 7C4h */
    ULONG glReserved1[0x1D];                /* B68h */
    PVOID glReserved2;                      /* BDCh */
    PVOID glSectionInfo;                    /* BE0h */
    PVOID glSection;                        /* BE4h */
    PVOID glTable;                          /* BE8h */
    PVOID glCurrentRC;                      /* BECh */
    PVOID glContext;                        /* BF0h */
    NTSTATUS LastStatusValue;               /* BF4h */
    UNICODE_STRING StaticUnicodeString;     /* BF8h */
    WCHAR StaticUnicodeBuffer[0x105];       /* C00h */
    PVOID DeallocationStack;                /* E0Ch */
    PVOID TlsSlots[0x40];                   /* E10h */
    LIST_ENTRY TlsLinks;                    /* F10h */
    PVOID Vdm;                              /* F18h */
    PVOID ReservedForNtRpc;                 /* F1Ch */
    PVOID DbgSsReserved[0x2];               /* F20h */
    ULONG HardErrorDisabled;                /* F28h */
    PVOID Instrumentation[14];              /* F2Ch */
    PVOID SubProcessTag;                    /* F64h */
    PVOID EtwTraceData;                     /* F68h */
    PVOID WinSockData;                      /* F6Ch */
    ULONG GdiBatchCount;                    /* F70h */
    BOOLEAN InDbgPrint;                     /* F74h */
    BOOLEAN FreeStackOnTermination;         /* F75h */
    BOOLEAN HasFiberData;                   /* F76h */
    UCHAR IdealProcessor;                   /* F77h */
    ULONG GuaranteedStackBytes;             /* F78h */
    PVOID ReservedForPerf;                  /* F7Ch */
    PVOID ReservedForOle;                   /* F80h */
    ULONG WaitingOnLoaderLock;              /* F84h */
    ULONG SparePointer1;                    /* F88h */
    ULONG SoftPatchPtr1;                    /* F8Ch */
    ULONG SoftPatchPtr2;                    /* F90h */
    PVOID *TlsExpansionSlots;               /* F94h */
    ULONG ImpersionationLocale;             /* F98h */
    ULONG IsImpersonating;                  /* F9Ch */
    PVOID NlsCache;                         /* FA0h */
    PVOID pShimData;                        /* FA4h */
    ULONG HeapVirualAffinity;               /* FA8h */
    PVOID CurrentTransactionHandle;         /* FACh */
    PTEB_ACTIVE_FRAME ActiveFrame;          /* FB0h */
    PVOID FlsData;                          /* FB4h */
    UCHAR SafeThunkCall;                    /* FB8h */
    UCHAR BooleanSpare[3];                  /* FB9h */
} TEB, *PTEB;
typedef struct _PEB
{
    UCHAR InheritedAddressSpace; // 00h
    UCHAR ReadImageFileExecOptions; // 01h
    UCHAR BeingDebugged; // 02h
    UCHAR Spare; // 03h
    PVOID Mutant; // 04h
    PVOID ImageBaseAddress; // 08h
    PPEB_LDR_DATA Ldr; // 0Ch
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters; // 10h
    PVOID SubSystemData; // 14h
    PVOID ProcessHeap; // 18h
    PVOID FastPebLock; // 1Ch
    PPEBLOCKROUTINE FastPebLockRoutine; // 20h
    PPEBLOCKROUTINE FastPebUnlockRoutine; // 24h
    ULONG EnvironmentUpdateCount; // 28h
    PVOID* KernelCallbackTable; // 2Ch
    PVOID EventLogSection; // 30h
    PVOID EventLog; // 34h
    PPEB_FREE_BLOCK FreeList; // 38h
    ULONG TlsExpansionCounter; // 3Ch
    PVOID TlsBitmap; // 40h
    ULONG TlsBitmapBits[0x2]; // 44h
    PVOID ReadOnlySharedMemoryBase; // 4Ch
    PVOID ReadOnlySharedMemoryHeap; // 50h
    PVOID* ReadOnlyStaticServerData; // 54h
    PVOID AnsiCodePageData; // 58h
    PVOID OemCodePageData; // 5Ch
    PVOID UnicodeCaseTableData; // 60h
    ULONG NumberOfProcessors; // 64h
    ULONG NtGlobalFlag; // 68h
    UCHAR Spare2[0x4]; // 6Ch
    LARGE_INTEGER CriticalSectionTimeout; // 70h
    ULONG HeapSegmentReserve; // 78h
    ULONG HeapSegmentCommit; // 7Ch
    ULONG HeapDeCommitTotalFreeThreshold; // 80h
    ULONG HeapDeCommitFreeBlockThreshold; // 84h
    ULONG NumberOfHeaps; // 88h
    ULONG MaximumNumberOfHeaps; // 8Ch
    PVOID** ProcessHeaps; // 90h
    PVOID GdiSharedHandleTable; // 94h
    PVOID ProcessStarterHelper; // 98h
    PVOID GdiDCAttributeList; // 9Ch
    PVOID LoaderLock; // A0h
    ULONG OSMajorVersion; // A4h
    ULONG OSMinorVersion; // A8h
    ULONG OSBuildNumber; // ACh
    ULONG OSPlatformId; // B0h
    ULONG ImageSubSystem; // B4h
    ULONG ImageSubSystemMajorVersion; // B8h
    ULONG ImageSubSystemMinorVersion; // C0h
    ULONG GdiHandleBuffer[0x22]; // C4h
    PVOID ProcessWindowStation; // ???
} PEB, *PPEB;
1.认识LDR链 FS段寄存器作为选择子指向当前的活动线程的TEB结构(Thread Environment Block)注释。在TEB偏移的0x30处,就是指向PEB(Process Environment Block)注释② 的指针。而在PEB偏移的0x0c处是指向PEB_LDR_DATA结构的指针。PEB_LDR_DATA的结构如下:
typedef struct _PEB_LDR_DATA
{
ULONG Length; // +0x00
BOOLEAN Initialized; // +0x04
PVOID SsHandle; // +0x08
LIST_ENTRY InLoadOrderModuleList; // +0x0c
LIST_ENTRY InMemoryOrderModuleList; // +0x14
LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA,*PPEB_LDR_DATA; // +0x24 我们看到,在PEB_LDR_DATA结构中,又包含三个LIST_ENTRY结构体分别命名为: InLoadOrderModuleList; 模块加载顺序
InMemoryOrderModuleList; 模块在内存中的顺序
InInitializationOrderModuleList; 模块初始化装载顺序 LIST_ENTRY其结构定义如下: typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY; 微软是怎么解释LIST_ENTRY结构中成员作用的呢?来看看MSDN The head of a doubly-linked list that contains the loaded modules for the process. Each item in the list is a pointer to an LDR_DATA_TABLE_ENTRY structure 这个双链表指向进程装载的模块,结构中的每个指针,指向了一个LDR_DATA_TABLE_ENTRY 的结构: 我们来看看这个结构的定义:
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
WORD LoadCount;
WORD TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
_ACTIVATION_CONTEXT * EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; (在0x028处获取 DllName的名称字符串)
@Windows XP Professional Service Pack 3 (x86) (5.1, Build 2600)
nt!_LDR_DATA_TABLE_ENTRY
……
……
+0x010 DllBase : Ptr32
+0x014 EntryPoint : Ptr32
+0x018 SizeOfImage : Uint4B
FullDllName : _UNICODE_STRING
+0x01c Length : Uint2B
+0x01e MaximumLength : Uint2B
+0x020 字符串地址Buffer : Ptr32
BaseDllName : _UNICODE_STRING
+0x024 Length : Uint2B
+0x026 MaximumLength : Uint2B
+0x028 字符串地址Buffer : Ptr32
……
……
可以根据上述的定义,画出一个直观寻址的示意图:

在定位到PEB_LDR_DATA 后,我们就可以根据之前介绍LDR_DATA_TABLE_ENTRY的结构,来定位每个模块的基址了。PEB_LDR_DATA地址知道了,那么,怎么根据它去找到LDR_DATA_TABLE_ENTRY呢?
前面提到过,PEB_LDR_DATA 中的三个LIST_ENTRY全部是双向链表结构,它的两个成员Flink,Blink都指向LDR_DATA_TABLE_ENTRY,那么,在真实的系统环境中,PEB_LDR_DATA 中的每一个LIST_ENTRY填充的是什么呢?与LDR_DATA_TABLE_ENTRY的关系又是怎么连接起来的呢?沐浴更衣,亮出神器windbg,一探究竟: 追本溯源,首先查看PEB结构:
0:000> !peb
PEB at 7ffd4000
Ldr.InInitializationOrderModuleList: 00202988 . 00202cb0
Ldr.InLoadOrderModuleList: 002028e8 . 00202db8
Ldr.InMemoryOrderModuleList: 002028f0 . 00202dc0
于此同时也获得各个加载模块的基地址:
400000 3db8972c Oct 25 08:58:20 2002 C:\Users\JoRrYChEn\Desktop\test.exe
77130000 4ec49caf Nov 17 13:33:35 2011 C:\Windows\SYSTEM32\ntdll.dll
76e00000 4e21132a J1ul 16 12:27:22 2011 C:\Windows\system32\kernel32.dll
751b0000 4e21132b Jul 16 12:27:23 2011 C:\Windows\system32\KERNELBASE.dll
我们看到,Ldr中有的三个List,根据MSDN规定LIST_ENTRY的结构,其中有两个成员:Flink和Blink,他们分别指向着一个LDR_DATA_TABLE_ENTRY 结构。各个LIST_ENTRY的第一个填充就是链表的Flink,指向下一个链表节点,第二个填充的是链表的Blink,指向前一个链表节点。那么根据windbg提供的PEB_LDR_DATA 中的三个LIST_ENTRY的Flink,来看看其填充的各项值: InLoadOrderModuleList: Flink :00202988 . Blink:00202cb0
0:000> dd 002028e8
002028e8 00202978 7720788c 00202980 77207894
002028f8 00000000 00000000 00400000 0040720b 0:000> dd 00202978
00202978 00202ca0 002028e8 00202ca8 002028f0
00202988 00202dc8 7720789c 77130000 00000000 0:000> dd 00202ca0
00202ca0 00202db8 00202978 00202dc0 00202980
00202cb0 7720789c 00202dc8 76e00000 76e51065 0:000> dd 00202db8
00202db8 7720788c 00202ca0 77207894 00202ca8
00202dc8 00202cb0 00202988 751b0000 751b7afd 0:000> dd 7720788c
7720788c 002028e8 00202db8 002028f0 00202dc0
7720789c 00202988 00202cb0 00000000 00000000 我们看到002028e8所在的模块地址是00400000,是原始模块加载基地址,它的Flink是00202978 ,所在的模块地址77130000 ,是ntdll.dll的加载基地址,它的Flink是00202ca0 ,所在的模块地址是76e00000 ,是kernel32.dll的加载基地址,它的Flink是00202db8 ,所在模块地址是751b0000,是KERNELBASE.dll的加载基地址。之后,便是一个循环,Flink又指向了002028e8。不难发现,这是个循环链表! 同理,我们依此遍历InMemoryOrderModuleList 和 InInitializationOrderModuleList两条链: Ldr.InMemoryOrderModuleList:
0:000> dd 002028f0
002028f0 00202980 77207894 00000000 00000000
00202900 00400000 0040720b 00008010 00460044 0:000> dd 00202980
00202980 00202ca8 002028f0 00202dc8 7720789c
00202990 77130000 00000000 0013c000 003c003a 0:000> dd 00202ca8
00202ca8 00202dc0 00202980 7720789c 00202dc8
00202cb8 76e00000 76e51065 000d4000 00420040 0:000> dd 00202dc0
00202dc0 77207894 00202ca8 00202cb0 00202988
00202dd0 751b0000 751b7afd 0004a000 00460044 0:000> dd 77207894
77207894 002028f0 00202dc0 00202988 00202cb0
772078a4 00000000 00000000 00000000 00000000 InInitializationOrderModuleList:
0:000>dd 00202988
00202988 00202dc8 7720789c 77130000 00000000 0:000> dd 00202dc8
00202dc8 00202cb0 00202988 751b0000 751b7afd 0:000> dd 00202cb0
00202cb0 7720789c 00202dc8 76e00000 76e51065 0:000> dd 7720789c
7720789c 00202988 00202cb0 00000000 00000000 同InLoadOrderModuleList 一样,最终,这也是双向的循环链表结构。根据我们遍历出来的结构,我们可以画出如下的示意图(test文件为例):

不难发现,PEB_LDR_DATA给出的是三个List(InLoadOrderModuleList,InMemoryOrderModuleLis以及InInitializationOrderModuleList)模块加载首个基址,也可以看成是整个List双向链表的表头,然后通过这个双向循环链表的不断的遍历,来依此获取不同List加载的顺序。同时系统为每一个DLL维护的一个LDR_DATA_TABLE_ENTRY,该结构中,每一个DLL在不同List中,不但包含着着前继加载模块或者后继加载模块,还有着非常详细的各个加载模块的信息,包括加载基址和DLL名称等等。
这样,我们可以关于之前根据PEB_LDR_DATA 后找到LDR_DATA_TABLE_ENTRY就非常的显而易见了:

通过不断地遍历,读取其中的各项结构,至此,我们可以得出每一个List的在测试系统(win7,目标EXE文件 test)下加载的依此顺序:
遍历 InInitializationOrderModuleList 得到次序:
NTDLL.DLL-> KERNELBASE.DLL->KERNEK32.DLL->NULL 遍历 InLoadOrderModuleList 得到次序 TEST.EXE->NTDLL.DLL-> KERNEK32.DLL->KERNELBASE.DLL->NULL 遍历 InMemoryOrderModuleList 得到次序
TEST.EXE->NTDLL.DLL-> KERNEK32.DLL->KERNELBASE.DLL->NULL 2.PEB_LDR_DATA链表的应用 我们都知道,以前在xp下写shellcode,最通用获得kernel32基址代码:
mov ebx, fs:[ 0x30 ] // 获得PEB
mov ebx, [ ebx + 0x0C ] // 获得PEB_LDR_DATA
mov ebx, [ ebx + 0x1C ] // InitializationOrderModuleList 第一项
mov ebx, [ ebx ] // InitializationOrderModuleList 第二项
mov ebx, [ ebx + 0x8 ] // 获得完整的路径地址
但是这段代码放到win7就不通用, 为什么?前三句没问题,首先是获得PEB基地址,然后在偏移0X0C处获得LDR,然后再取得LDR的偏移 0x1C处,获得InInitializationOrderModuleList加载的下一个模块基址,恰恰问题是出在第5句上,mov ebx,[ebx],此时,ebx中的值按照前面所述,应该是第二个LDR_DATA_TABLE_ENTRY,可是根据之前的观察,在win7的环境之下,InInitializationOrderModuleList第二个LDR_DATA_TABLE_ENTRY不是kernel32了,而是,KERNELBASE了(见图2),kernel32排到了第三个了。所以,若要获取win7下kernel32的基址,只需将之前的代码略加修改:
mov ebx, fs:[ 0x30 ] // 获得PEB
mov ebx, [ ebx + 0x0C ] // 获得PEB_LDR_DATA
mov ebx, [ ebx + 0x1C ] // InitializationOrderModuleList第一项
mov ebx, [ ebx ] // InitializationOrderModuleList第二项
mov ebx, [ ebx ] // InitializationOrderModuleList第三项
mov ebx, [ ebx + 0x8 ] // 获得完整的路径地址
当然,若要想写一个通用的shellcode,就必须先要判断系统版本号再根据情况来确定是取链的第二项还是第三项。除开现有的字符串查找方法,有木有一个更为快捷的方法呢?我们试着来探讨一下: 前辈们的经验告诉我们,winXp下,InitializationOrderModuleList 加载的DLL模块顺序是固定的,通过遍历其链,kernel32.dll必然是在第二位。但是在win7条件下,这个xp下固定的“第二位”就已经换成了KERNELBASE.DLL了。那么另外两条InMemoryOrderModuleList和 InLoadOrderModuleList是不是模块加载顺序也变了呢?是不是也能像类似于查找InitializationOrderModuleList顺序链的方式找到通用的加载顺序呢? 带着疑问,写一个遍历PEB.LDR.InLoadOrderModuleList程序验证一下:
Win2000+Sp4下:

winxp+sp3
win7

结果不难发现,InLoadOrderModuleList在所有上述系统中,按照顺序:第一个是EXE模块本身的ImageBase,第二个是NTDLL.DLL,第三个是KERNEL32.DLL。这样,KERNEL32.DLL的顺序是不是又固定了呢?
mov ebx, fs:[ 0x30 ] // 获得PEB
mov ebx, [ ebx + 0x0C ] // 获得PEB_LDR_DATA
mov ebx, [ ebx + 0x0C ] // InLoadOrderModuleList第一项
mov ebx, [ ebx ] // InLoadOrderModuleList第二项
mov ebx, [ ebx ] // InLoadOrderModuleList第三项
mov ebx, [ ebx + 0x18 ] // 获得完整的路径地址,此时偏移0x18
同理,InMemoryOrderModuleList也可以发现类似的规律。
写完这篇手记之后,越觉得不对劲,这么浅显的方法为什么没有被拿来通用,google了一下,原来,早在09年,就有某牛总结出来了:
http://blog.harmonysecurity.com/2009/06/retrieving-kernel32s-base-address.html
文章用到的是InMemoryOrderModuleList链,至于遍历这些链为什么没有成为通用的方法,很显然,作者在后面加上了如是说明:
Their appears to be some cases on Windows 2000 whereby the above method will not yield the correct result.
提到了在2000平台下,某些例子可能会得到错误的结果,最后提出来查找hash函数名的方法,这个和以前可以某些病毒在IAT里面找从kernel32.dll引入的函数,向上找“MZ”头方法很类似,同样也是依靠遍历LDR链,只不过比较的就是DllName了。详细的代码请参考上文连接:D。 注释:
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/TEB.html
注释②
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html
PEB及LDR链的更多相关文章
- 通过PEB的Ldr枚举进程内所有已加载的模块
		一.几个重要的数据结构,可以通过windbg的dt命令查看其详细信息 _PEB._PEB_LDR_DATA._LDR_DATA_TABLE_ENTRY 二.技术原理 1.通过fs:[30h]获取当前进 ... 
- 【旧文章搬运】再谈隐藏进程中的DLL模块
		原文发表于百度空间,2009-09-17========================================================================== 相当老的话 ... 
- X64驱动:内核操作进线程/模块
		注意:下面的所有案例必须使用.C结尾的文件,且必须在链接选项中加入 /INTEGRITYCHECK 选项,否则编译根本无法通过(整合修正,Win10可编译,须在测试模式下进行),内核代码相对固定,如果 ... 
- Win64 驱动内核编程-7.内核里操作进程
		在内核里操作进程 在内核里操作进程,相信是很多对 WINDOWS 内核编程感兴趣的朋友第一个学习的知识点.但在这里,我要让大家失望了,在内核里操作进程没什么特别的,就标准方法而言,还是调用那几个和进程 ... 
- Windows x64位通过PEB获得Kernel32基地址
		在64位系统下 gs:[0x30] 指向TEB gs:[0x60] 指向PEB kd> dt _TEB nt!_TEB +0x000 NtTib : _NT_TIB +0x000 Excepti ... 
- 通过PEB寻找函数地址
		通过PEB的Ldr参数(结构体定义为_PEB_LDR_DATA),遍历当前进程加载的模块信息链表,找到目标模块. 摘自PEB LDR DATA: typedef struct _PEB_LDR ... 
- Windows x86/ x64 Ring3层注入Dll总结
		欢迎转载,转载请注明出处:http://www.cnblogs.com/uAreKongqi/p/6012353.html 0x00.前言 提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线 ... 
- [转]DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)
		在CSDN中发现这篇文章,讲解的比较详细,所以在这里备份一个.原文链接:http://blog.csdn.net/breaksoftware/article/details/8167641 DllMa ... 
- 无LoadLibrary获取指定模块基址
		实际上,这块可以写成汇编,然后做远程注入用 方法 1.通过fs:[30h]获取当前进程的_PEB结构 2.通过_PEB的Ldr成员获取_PEB_LDR_DATA结构 3.通过_PEB_LDR_DATA ... 
随机推荐
- 第167天:canvas绘制柱状图
			canvas绘制柱状图 1.HTML <!DOCTYPE html> <html lang="en"> <head> <meta char ... 
- 第83天:jQuery中操作form表单
			操作form表单 1. 属性操作 设置属性: // 第一个参数表示:要设置的属性名称 // 第二个参数表示:该属性名称对应的值 $(selector).attr(“title”, “传智播客”); 获 ... 
- CIR,CBS,EBS,PIR,PBS  名词解释 令牌桶应用
			为了达到上述目的,我们需要对进入网络的流量进行监督,实现CAR(Committed Access Rate). CAR:将进入网络的用户流量的速率限制在约定的范围之内,从而避免引起网络拥塞. CIR( ... 
- java.lang - 不用import
			java.lang包是java语言的核心,它提供了java中的基础类.包括基本Object类.Class类.String类.基本类型的包装类.基本的数学类等等最基本的类.我们介绍一下Java 8中的j ... 
- Android Native jni 编程 Android.mk 文件编写
			LOCAL_PATH 必须位于Android.mk文件的最开始.它是用来定位源文件的位置,$(call my-dir)的作用就是返回当前目录的路径. LOCAL_PATH := $(call my-d ... 
- 【bzoj4198】【Noi2015】荷马史诗
			4198: [Noi2015]荷马史诗 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2200 Solved: 1169[Submit][Statu ... 
- atom插件安装引发的nodejs和npm安装血案
			最近在写前端网页,学习就要从高大上的地方开始,于是我打算装一个atom编辑器. 本来就是由github客户端的,再装个atom也算是配套了吧,其实本白也是蛮费心思的,技术不怎么地,什么神器都再努力地使 ... 
- 图像处理之中值滤波介绍及C实现
			1 中值滤波概述 中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号平滑处理技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值. 中值滤波的基本原理是把数字图像或数字序 ... 
- 图像RGB格式与YUV格式互转
			// rgb2yuv.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #define Level 256 //直方图bin数 #define ... 
- EA画时序图初试
			1.步骤: 1. 新建一个项目: 2. Use Case Model右键-->添加图-->左边选择UML Behavioral,右边选择Sequence: 3. 选择工具栏中的工具,点击工 ... 
