首页 各种反调试技术原理与实例汇编版

各种反调试技术原理与实例汇编版

举报
开通vip

各种反调试技术原理与实例汇编版 http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 反调试技术...............................................................................................................................2 发现 OD 的处理 ..........................................

各种反调试技术原理与实例汇编版
http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 反调试技术...............................................................................................................................2 发现 OD 的处理 ...............................................................................................................2 1. 窗口类名、窗口名...................................................................................................3 2. 检测调试器进程.......................................................................................................4 3. 父进程是否是 Explorer............................................................................................5 4. RDTSC/ GetTickCount 时间敏感程序段 ................................................................7 5. StartupInfo 结构........................................................................................................7 6. BeingDebugged.........................................................................................................9 7. PEB.NtGlobalFlag , Heap.HeapFlags, Heap.ForceFlags ........................................10 8. DebugPort: CheckRemoteDebuggerPresent()/NtQueryInformationProcess()........11 9. SetUnhandledExceptionFilter/ Debugger Interrupts ...............................................13 10. Trap Flag 单步标志异常 ....................................................................................15 11. SeDebugPrivilege 进程权限..............................................................................16 12. DebugObject: NtQueryObject() ..........................................................................16 13. OllyDbg:Guard Pages ......................................................................................17 14. Software Breakpoint Detection ...........................................................................19 15. Hardware Breakpoints.........................................................................................21 16. PatchingDetection CodeChecksumCalculation 补丁检测,代码检验和 ..........22 17. block input 封锁键盘、鼠标输入......................................................................23 18. EnableWindow 禁用窗口 ...................................................................................23 19. ThreadHideFromDebugger .................................................................................24 20. Disabling Breakpoints 禁用硬件断点 ................................................................26 21. OllyDbg:OutputDebugString() Format String Bug.............................................27 22. TLS Callbacks.....................................................................................................28 反反调试技术.................................................................................................................31 http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 反反反反调试调试调试调试技术技术技术技术 唐久涛 看雪 ID:tangjiutao 本人空间:http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等。 声明:这篇文章是本人学习的总结,理论部分参考了《脱壳的艺术》、《加密与解密》以及本人从网络上收 集的资料,在此向原作者致敬。本人的贡献在于根据个人理解对各种反调试技术进行了汇总和高度归纳, 并提供了本人创作的各种反调试实例及源代码。本人于 09 年 9 月份开始学习软件逆向 工程 路基工程安全技术交底工程项目施工成本控制工程量增项单年度零星工程技术标正投影法基本原理 的相关知识,在 学习过程中得到大量网友的热心帮助,在此向各位致以诚挚谢意。希望本人的这些工作能够对各位有所帮 助,浅陋之处,莫要见笑。各种形式的转载都必须保留作者信息及本声明。 由于本人入门较晚、能力有限,部分方法尚未实现,望高手不吝赐教。实现了的方法大都附有实例程序。 很多方法对于修改版的 OD 已经失效,请用原版 OD 进行测试。 发现发现发现发现 OD 的处理的处理的处理的处理 一、如何获取 OD 窗口的句柄 1.已经获取了窗口类名或标题:FindWindow 2.没有获取窗口类名或标题没有获取窗口类名或标题没有获取窗口类名或标题没有获取窗口类名或标题::::GetForeGroundWindow 返回前台窗口返回前台窗口返回前台窗口返回前台窗口,,,,这里就是这里就是这里就是这里就是 OD 的窗口的窗口的窗口的窗口 句柄句柄句柄句柄了了了了。。。。注意这种方法更为重要注意这种方法更为重要注意这种方法更为重要注意这种方法更为重要,,,,因为大多数情况下不会知道因为大多数情况下不会知道因为大多数情况下不会知道因为大多数情况下不会知道 OD 的的的的窗口类名窗口类名窗口类名窗口类名。。。。 invoke IsDebuggerPresent .if eax invoke GetForegroundWindow ;获得的是 OD 的窗口句柄 invoke SendMessage,eax,WM_CLOSE,NULL,NULL .endif 二、获取 OD 窗口句柄后的处理 (1)向窗口发送 WM_CLOSE 消息 invoke FindWindow,addr szClassName,NULL ;通过类名进行检测 .if eax ;找到 mov hWinOD,eax invoke MessageBox,NULL,offset szFound,offset szCaption,MB_OK invoke SendMessage,hWinOD,WM_CLOSE,NULL,NULL .endif (2)使 OD 窗口不可用 HWND hd_od=FindWindow("ollydbg",NULL); SetWindowLong(hd_od,GWL_STYLE,WS_DISABLED); (3)终止相关进程,根据窗口句柄获取进程 ID,根据进程 ID 获取进程句柄, _GetODProcID proc LOCAL @hWinOD ;窗口句柄 LOCAL @hProcessOD ;进程句柄 LOCAL @idProcessOD ;进程 ID invoke FindWindow,addr szClassName,NULL ;通过类名进行检测 .if eax ;找到 mov @hWinOD,eax ;窗口句柄 invoke GetWindowThreadProcessId,@hWinOD,addr @idProcessOD http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 ;获取进程 ID 在@idProcessOD 里 invoke OpenProcess,PROCESS_TERMINATE,TRUE,@idProcessOD ;获取进程句柄在返回值里 .if eax ;获取句柄成功 mov @hProcessOD,eax invoke TerminateProcess,@hProcessOD,200 ;利用句柄终止进程 invoke CloseHandle,@hProcessOD ;关闭进程句柄 invoke MessageBox,NULL,addr szClose,addr szMerry,MB_OK .else ;获取句柄失败,多因权限问题 invoke MessageBox,NULL,addr szFail,addr szCaption,MB_OK .endif . .endif ret _GetODProcID endp 1. 窗口类名窗口类名窗口类名窗口类名、、、、窗口名窗口名窗口名窗口名 (1) FindWindow (2) EnumWindow 函数调用后,系统枚举所有顶级窗口,为每个窗口调用一次回调函数。 在回调函数中用 GetWindowText 得到窗口标题,用 strstr 等函数查找有无 Ollydbg 字 符串。StrStr(大小写敏感,对应的 StrStrI 大小写不敏感)函数返回 str2 第一次出现在 str1 中的位置,如果没有找到,返回 NULL。 (3) GetForeGroundWindow 返回前台窗口(用户当前工作的窗口)。当程序被调试时,调 用这个函数将获得 Ollydbg 的窗口句柄,这样就可以向其发送 WM_CLOSE 消息将 其关闭了。 (1)FindWindow szClassName db 'ollydbg',0 invoke FindWindow,addr szClassName,NULL ;通过类名进行检测 .if eax ;找到 jmp debugger_found .endif (2)EnumWindow .386 .model flat,stdcall option casemap:none include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib include Shlwapi.inc includelib Shlwapi.lib ;strstr .const http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 szTitle db 'ollydbg',0 szCaption db '结果',0 szFindOD db '发现目标窗口',0 szText db '枚举已结束,没提示发现目标,则没有找到目标窗口',0 .code ;定义回调函数 _CloseWnd proc uses ebx edi esi,_hWnd,_lParam LOCAL @szBuffer[1024]:BYTE ;接收窗口标题 invoke IsWindowVisible,_hWnd .if eax ;是否是可见的窗口 invoke GetWindowText,_hWnd,addr @szBuffer,sizeof @szBuffer invoke StrStrI,addr @szBuffer,offset szTitle ;查找标题中有无字符串,不带 I 的 大小写敏感 .if eax invoke MessageBox,NULL,addr szFindOD,addr szCaption,MB_OK invoke PostMessage,_hWnd,WM_CLOSE,0,0 ;关闭目标 .endif .endif mov eax,TRUE ;返回 true 时,EnumWindows 继续枚举下一个窗口,false 退出枚 举. ret _CloseWnd endp start: invoke EnumWindows,addr _CloseWnd,NULL ;EnumWindows 调用,系统枚举所有顶级窗口,为每个窗口调用一次回调函数 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK invoke ExitProcess,NULL end start 2. 检测调试器进程 枚举进程列 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf ,看是否有调试器进程(OLLYDBG.EXE,windbg.exe 等)。 利用 kernel32!ReadProcessMemory()读取进程内存,然后寻找调试器相关的字符串(如” OLLYDBG”)以防止逆向分析人员修改调试器的可执行文件名。 .386 .model flat, stdcall option casemap :none include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib .const http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 stSysProc db 'OLLYDBG.EXE',0 szCaption db '检测结果',0 szFound db '检测到调试器',0 szNotFound db '没有调试器',0 .code _GetProcList proc LOCAL @stProcessEntry:PROCESSENTRY32 LOCAL @hSnapShot invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,NULL mov @hSnapShot,eax mov @stProcessEntry.dwSize,sizeof @stProcessEntry invoke Process32First,@hSnapShot,addr @stProcessEntry .while eax invoke lstrcmp,addr @stProcessEntry.szExeFile,addr stSysProc .if eax == 0 ;为 0,说明进程名相同 push 20 invoke MessageBox,NULL,addr szFound,addr szCaption,MB_OK .endif invoke Process32Next,@hSnapShot,addr @stProcessEntry .endw pop eax .if eax != 20 invoke MessageBox,NULL,addr szNotFound,addr szCaption,MB_OK .endif ret _GetProcList endp start: invoke _GetProcList invoke ExitProcess,NULL end start 3. 父进程是否是父进程是否是父进程是否是父进程是否是 Explorer 原理:通常进程的父进程是 explorer.exe(双击执行的情况下),否则可能程序被调试。 下面是实现这种检查的一种方法: 1.通过 TEB(TEB.ClientId)或者使用 GetCurrentProcessId()来检索当前进程的 PID 2.用 Process32First/Next()得到所有进程的列表,注意 explorer.exe 的 PID(通过 PROCESSENTRY32.szExeFile)和通过 PROCESSENTRY32.th32ParentProcessID 获得的当前 进程的父进程 PID。Explorer 进程 ID 也可以通过桌面窗口类和名称获得。 3.如果父进程的 PID 不是 explorer.exe,cmd.exe,Services.exe 的 PID,则目标进程很可能 被调试 对策:Olly Advanced 提供的方法是让 Process32Next()总是返回 fail,使进程枚举失效,PID 检查将会被跳过。这些是通过补丁 kernel32!Process32NextW()的入口代码(将 EAX 值设为 http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 0 然后直接返回)实现的。 (1)通过桌面类和名称获得 Explorer 的 PID 源码见附件 .data? szDesktopClass db 'Progman',0 ;桌面的窗口类 szDesktopWindow db 'Program Manager',0 ;桌面的窗口名称 dwProcessID dd ? ;保存进程 ID dwThreadID dd ? ;保存线程 ID .code invoke FindWindow,addr szDesktopClass,addr szDesktopWindow ;获取桌面窗口句柄 invoke GetWindowThreadProcessId,eax,offset dwProcessID ;获取 EXPLORER 进程 ID mov dwThreadID,eax ;线程 ID (2)通过进程列表快照获得 Explorer 的 PID 源码见附件 szExplorer db 'EXPLORER.EXE',0 dwParentID dd ? dwExplorerID dd ? _ProcTest proc local @stProcess:PROCESSENTRY32 ;每一个进程的信息 local @hSnapShot ;快照句柄 pushad invoke GetCurrentProcessId mov ebx,eax ;当前进程 ID invoke RtlZeroMemory,addr @stProcess,sizeof @stProcess ; 0 初始化进程信息结构 mov @stProcess.dwSize,sizeof @stProcess ;手工填写结构大小 invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0;获取进程列表快照 mov @hSnapShot,eax ;快照句柄 invoke Process32First,@hSnapShot,addr @stProcess ;第一个进程 .while eax .if ebx == @stProcess.th32ProcessID ;是当前进程吗? mov eax,@stProcess.th32ParentProcessID ;是,则保存父进程 ID mov dwParentID,eax .endif invoke lstrcmp,addr @stProcess.szExeFile,addr szExplorer ;Explorer 进程 ID .if eax == 0 ;为 0,说明进程名相同 mov eax,@stProcess.th32ProcessID mov dwExplorerID,eax .endif invoke Process32Next,@hSnapShot,addr @stProcess ;下一个进程 .endw invoke CloseHandle,@hSnapShot ;关闭快照 mov ebx,dwParentID .if ebx == dwExplorerID ;父进程 ID 与 EXPLORER 进程 ID 比较 invoke MessageBox,NULL,offset szNotFound,offset szCaption,MB_OK http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 .else invoke MessageBox,NULL,offset szFound,offset szCaption,MB_OK .endif popad ret _ProcTest endp 4. RDTSC/ GetTickCount 时间敏感程序段时间敏感程序段时间敏感程序段时间敏感程序段 当进程被调试时,调试器事件处理代码、步过指令等将占用 CPU 循环。如果相邻指令 之间所花费的时间如果大大超出常规,就意味着进程很可能是在被调试。 (1)RDTSC 将计算机启动以来的 CPU 运行周期数放到 EDX:EAX 里面,EDX 是高位,EAX 是低位。 如果 CR4 的 TSD(time stamp disabled)置位,则 rdtsc 在 ring3 下运行会导致异常(特权指令),所 以进入 ring0,把这个标记置上,然后 Hook OD 的 WaitForDebugEvent,拦截异常事件,当异常代 码 为 特 权 指 令 时 , 把 异 常 处 的 opcode 读 出 检 查 , 如 果 是 rdtsc, 把 eip 加 2,SetThreadContext,edx:eax 的返回由你了。 (2)GetTickCount 源码见附件 invoke GetTickCount ;第一次调用 mov ebx,eax ;结果保存在 ebx 里 mov ecx,10 ;延时开始 mov edx,6 ;单步走,放慢速度 mov ecx,10 ;延时结束 invoke GetTickCount ;第二次调用 sub eax,ebx ;计算差值 .if eax > 1000 ;假定大于 1000ms,就说明有调试器 jmp debugger_found .endif 5. StartupInfo 结构结构结构结构 原理:Windows 操作系统中的 explorer.exe 创建进程的时候会把 STARTUPINFO 结构中的 值设为 0,而非 explorer.exe 创建进程的时候会忽略这个结构中的值,也就是结构中的值不为 0,所以可以利用这个来判断 OD 是否在调试程序. if (Info.dwX<>0) or (Info.dwY<>0) or (Info.dwXCountChars<>0) or (Info.dwYCountChars<>0) or (Info.dwFillAttribute<>0) or (Info.dwXSize<>0) or (Info.dwYSize<>0) then “有调试器” ******************************************************************************* 结构体 typedef struct _STARTUPINFO { DWORD cb; 0000 http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 PSTR lpReserved; 0004 PSTR lpDesktop; 0008 PSTR lpTitle; 000D DWORD dwX; 0010 DWORD dwY; 0014 DWORD dwXSize; 0018 DWORD dwYSize; 001D DWORD dwXCountChars; 0020 DWORD dwYCountChars; 0024 DWORD dwFillAttribute; 0028 DWORD dwFlags; 002D WORD wShowWindow; 0030 WORD cbReserved2; 0034 PBYTE lpReserved2; 0038 HANDLE hStdInput; 003D HANDLE hStdOutput; 0040 HANDLE hStdError; 0044 } STARTUPINFO, *LPSTARTUPINFO; _ProcTest proc LOCAL @stStartupInfo:STARTUPINFO pushad invoke GetStartupInfo,addr @stStartupInfo cmp @stStartupInfo.dwX,0 jnz foundDebugger cmp @stStartupInfo.dwY,0 jnz foundDebugger cmp @stStartupInfo.dwXCountChars,0 jnz foundDebugger cmp @stStartupInfo.dwYCountChars,0 jnz foundDebugger cmp @stStartupInfo.dwFillAttribute,0 jnz foundDebugger cmp @stStartupInfo.dwXSize,0 jnz foundDebugger cmp @stStartupInfo.dwYSize,0 jnz foundDebugger noDebugger: “无调试器” jmp TestOver foundDebugger: “有调试器” TestOver: popad ret _ProcTest endp http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 6. BeingDebugged kernel32!IsDebuggerPresent() API 检测进程环境块(PEB)中的 BeingDebugged 标志检查这个标 志以确定进程是否正在被用户模式的调试器调试。 每个进程都有 PEB 结构,一般通过 TEB 间接得到 PEB 地址 Fs:[0]指向当前线程的 TEB 结构,偏移为 0 处是线程信息块结构 TIB TIB 偏移 18H 处是 self 字段,是 TIB 的反身指针,指向 TIB(也是 PEB)首地址 TEB 偏移 30H 处是指向 PEB 结构的指针 PEB 偏移 2H 处,就是 BeingDebugged 字段,Uchar 类型 (1) 调用 IsDebuggerPresent 函数,间接读 BeingDebugged 字段 (2) 利用地址直接读 BeingDebugged 字段 对策: (1) 数据窗口中 Ctrl+G fs:[30] 查看 PEB 数据,将 PEB.BeingDebugged 标志置 0 (2) Ollyscript 命令"dbh"可以补丁这个标志 .386 .model flat,stdcall option casemap:none include windows.inc include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib .const szCaption db '检测结果',0 szFound db '检测到调试器',0 szNotFound db '没有调试器',0 .code start: ;调用函数 IsDebuggerPresent invoke IsDebuggerPresent .if eax invoke MessageBox,NULL,addr szFound,addr szCaption,MB_OK .else invoke MessageBox,NULL,addr szNotFound,addr szCaption,MB_OK .endif ;直接去读字段 assume fs:nothing mov eax,fs:[30h] movzx eax,byte ptr [eax+2] .if eax invoke MessageBox,NULL,addr szFound,addr szCaption,MB_OK .else invoke MessageBox,NULL,addr szNotFound,addr szCaption,MB_OK .endif http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 invoke ExitProcess,NULL end start 7. PEB.NtGlobalFlag , Heap.HeapFlags, Heap.ForceFlags (1)通常程序没有被调试时,PEB 另一个成员 NtGlobalFlag(偏移 0x68)值为 0,如果进 程被调试通常值为 0x70(代表下述标志被设置): FLG_HEAP_ENABLE_TAIL_CHECK(0X10) FLG_HEAP_ENABLE_FREE_CHECK(0X20) FLG_HEAP_VALIDATE_PARAMETERS(0X40) 这些标志是在 ntdll!LdrpInitializeExecutionOptions()里设置的。请注意 PEB.NtGlobalFlag 的默 认值可以通过 gflags.exe 工具或者在注册表以下位置创建条目来修改: HKLM\Software\Microsoft\Windows Nt\CurrentVersion\Image File Execution Options assume fs:nothing mov eax,fs:[30h] mov eax,[eax+68h] and eax,70h ( 2 )由于 NtGlobalFlag 标志的设置,堆也会打开几个标志,这个变化可以在 ntdll!RtlCreateHeap()里观测到。正常情况下系统为进程创建第一个堆时会将 Flags 和 ForceFlags 分别设为 2(HEAP_GROWABLE)和 0 。当进程被调试时,这两个标志通常被设 为 50000062(取决于 NtGlobalFlag)和 0x40000060(等于 Flags AND 0x6001007D)。 assume fs:nothing mov ebx,fs:[30h] ;ebx 指向 PEB mov eax,[ebx+18h] ;PEB.ProcessHeap cmp dword ptr [eax+0ch],2 ;PEB.ProcessHeap.Flags jne debugger_found cmp dword ptr [eax+10h],0 ;PEB.ProcessHeap.ForceFlags jne debugger_found 这 些 标 志 位 都 是 因 为 BeingDebugged 引 起 的 。 系 统 创 建 进 程 的 时 候 设 置 BeingDebugged=TRUE , 后 来 NtGlobalFlag 根 据 这 个 标 记 设 置 FLG_VALIDATE_PARAMETERS 等标记。在为进程创建堆时,又由于 NtGlobalFlag 的作用, 堆的 Flags 被设置了一些标记,这个 Flags 随即被填充到 ProcessHeap 的 Flags 和 ForceFlags 中,同时堆中被填充了很多 BAADF00D 之类的东西(HeapMagic,也可用来检测调试)。 一次性解决这些状态见加密解密 P413 .386 .model flat,stdcall option casemap:none include windows.inc include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib .const szCaption db '检测结果',0 http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 szFound db '检测到调试器',0 szNotFound db '没有调试器',0 .code start: assume fs:nothing mov ebx,fs:[30h] ;ebx 指向 PEB ;PEB.NtGlobalFlag mov eax,[ebx+68h] cmp eax,70h je debugger_found ;PEB.ProcessHeap mov eax,[ebx+18h] ;PEB.ProcessHeap.Flags cmp dword ptr [eax+0ch],2 jne debugger_found ;PEB.ProcessHeap.ForceFlags cmp dword ptr [eax+10h],0 jne debugger_found invoke MessageBox,NULL,addr szNotFound,addr szCaption,MB_OK jmp exit debugger_found: invoke MessageBox,NULL,addr szFound,addr szCaption,MB_OK exit: invoke ExitProcess,NULL end start 8. DebugPort: CheckRemoteDebuggerPresent()/NtQueryInformationProcess() Kernel32!CheckRemoteDebuggerPresent()是用于确定是否有调试器被附加到进程。 BOOL CheckRemoteDebuggerPresent( HANDLE hProcess, PBOOL pbDebuggerPresent ) Kernel32!CheckRemoteDebuggerPresent()接受 2 个参数,第 1 个参数是进程句柄,第 2 个参 数是一个指向 boolean 变量的指针,如果进程被调试,该变量将包含 TRUE 返回值。 这个 API 内部调用了 ntdll!NtQueryInformationProcess(),由它完成检测工作。 .386 .model flat,stdcall option casemap:none include windows.inc http://ucooper.com 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP 网站建设、Wordpress 应用等 include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib .data? dwResult dd ? .const szCaption db '检测结果',0 szFound db '检测到调试器',0 szNotFound db '没有调试器',0 .code start: invoke GetCurrentProcessId invoke OpenProcess,PROCESS_ALL_ACCESS,NULL,eax invoke CheckRemoteDebuggerPresent,eax,addr dwResult cmp dword ptr dwResult,0 jne debugger_found
本文档为【各种反调试技术原理与实例汇编版】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_652222
暂无简介~
格式:pdf
大小:389KB
软件:PDF阅读器
页数:32
分类:互联网
上传时间:2010-10-04
浏览量:62