动态获取API的地址

2023-05-16

原理

现在虽然大部分Win32程序都使用ExitProcess函数来终止执行,但是其实用ret指令也是可以的。我们的应用程序的主程序可以被看成是一个被Windows调用的子程序。当父进程要创建一个子进程时,它会调用Kernel32.dll中的CreateProcess函数,CreateProcess函数在完成装载应用程序后,就会把一个返回地址用push压入栈,这个返回地址是子进程用ret来结束函数的时候要返回到的地方,返回到这后父进程会用ExitThread来结束这个线程,如果这个线程是子进程的最后一个线程的话,父进程就会再调用ExitProcess函数来结束子进程。重要的是:子进程返回到的地址,也就是父进程创建完子进程后压入栈的那个地址,是处于Kernel32.dll中的。所以,我们可以在程序中一开始就获取堆栈里的内容,这样我们就得到了一个处于Kernel32.dll中的地址,然后我们再顺着这个地址往低地址查询,直到找到PE文件头,那么我们就可以确定Kernel32.dll的起始地址了。得到了它的地址,我们可以根据函数名,通过数据目录找到导出表的地址,然后再遍历查找到GetProAddress函数的地址,有了这个函数,我们就可以轻松得到其他函数的地址了,当然我们还要得到LoadLibrary函数的地址,这样我们就可以得到其他动态链接库的基址了。

要注意的是,PE文件被装入内存时是按照64KB对齐的,所以Kernel32.dll的基址肯定也在某一个大小为64KB的页的开始部位,所以我们只要按照这个大小去找,就能找到Kernel32.dll的基址。

获取Kernel32.dll基址和GetProcAddress函数的入口地址的功能的代码放在一个函数中了,代码如下(参数_dwKernelRet就是程序一开始从SP处取得的值):

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;错误Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SEHHandler		proc	C _lpExceptionRecord,_lpSEH,\
						_lpContext,_lpDispatcherContext
						
				pushad
				mov		esi,_lpExceptionRecord
				mov		edi,_lpContext
				assume	esi:ptr EXCEPTION_RECORD,edi: ptr CONTEXT
				mov		eax,_lpSEH
				push	[eax + 0ch]			;恢复ebp
				pop		[edi].regEbp		;
				push	[eax + 8]
				pop		[edi].regEip		;设置IP指向发生中断后要执行的代码的位置
				push	eax
				pop		[edi].regEsp		;恢复ESP
				assume	esi:nothing,edi:nothing
				popad
				mov		eax,ExceptionContinueExecution
				ret
				
_SEHHandler		endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;在内存中扫描Kernel32.dll的基址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetKernelBase	proc	_dwKernelRet
				local	@dwReturn
				
				pushad
				mov		@dwReturn,0
;***************************************************************************************************
;重定位
;***************************************************************************************************
				call	@F
				@@:
				pop		ebx
				sub		ebx,offset @B		;获得偏移
;****************************************************************************************************
;创建用于错误处理的SEH结构
;****************************************************************************************************
				assume	fs:nothing
				push	ebp
				lea		eax,[ebx + offset _PageError]		;修正代码位置
				push	eax
				lea		eax,[ebx + offset _SEHHandler]		;中断处理函数的位置
				push	eax
				push	fs:[0]
				mov		fs:[0],esp
;*******************************************************************************************************
;查找Kernel32.dll的基地址
;*******************************************************************************************************
				mov		edi,_dwKernelRet
				and		edi,0ffff0000h						;取高位
				.while	TRUE
						.if		word ptr [edi] == IMAGE_DOS_SIGNATURE			;查看第一个字段,判断是否是DOS文件头
								mov		esi,edi
								add		esi,[esi + 003ch]						;加上指向PE文件头的偏移
								.if	word ptr [esi] == IMAGE_NT_SIGNATURE		;判断是否是PE头
										mov		@dwReturn,edi					;
										.break
								.endif
						.endif
						_PageError:
						sub		edi,010000h										;向上寻找,一直找到Kernel32.dll的基地址为止(PE文件被装入内存时按照64KB对齐的)
						.break	.if	edi < 070000000h
				.endw
				pop		fs:[0]							;恢复原来的SEH链
				add		esp,0ch
				popad	
				mov		eax,@dwReturn
				ret
				
_GetKernelBase	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;从内存中模块的导出表中获取某个API的入口地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetApi			proc	_hModule,_lpszApi
				local	@dwReturn,@dwStringLength
				
				pushad
				mov		@dwReturn,0
;***************************************************************************************************************
;重定位
;***************************************************************************************************************
				call	@F
				@@:
				pop		ebx
				sub		ebx,offset @B					;获取偏移
;****************************************************************************************************************
;创建用于错误处理的SEH结构
;****************************************************************************************************************
				assume	fs:nothing
				push	ebp
				lea		eax,[ebx + offset _Error]		;修正代码位置
				push	eax
				lea		eax,[ebx + offset _SEHHandler]	;中断处理函数
				push	eax
				push	fs:[0]
				mov		fs:[0],esp
;*****************************************************************************************************************
;计算API字符串的长度(带尾部的0)
;*****************************************************************************************************************
				mov		edi,_lpszApi
				mov		ecx,-1
				xor		al,al
				cld
				repnz	scasb							;于指定区域扫描制定字符,区域由ES:DI及CX指定。字符由AL指定。如果找到ES:DI指向该字符,ZF=1,否则,ZF=0 
				mov		ecx,edi
				sub		ecx,_lpszApi					;减去字符串基地址得到字符串长度
				mov		@dwStringLength,ecx
;******************************************************************************************************************
;从PE文件头的数据目录获取导出表的位置
;******************************************************************************************************************
				mov		esi,_hModule
				add		esi,[esi + 3ch]
				assume	esi:ptr IMAGE_NT_HEADERS
				mov		esi,[esi].OptionalHeader.DataDirectory.VirtualAddress	;获取导出表的RVA
				add		esi,_hModule
				assume	esi:ptr IMAGE_EXPORT_DIRECTORY
;*******************************************************************************************************************
;查找符合条件名称的导出函数名
;*******************************************************************************************************************
				mov		ebx,[esi].AddressOfNames
				add		ebx,_hModule
				xor		edx,edx
				.repeat
						push	esi
						mov		edi,[ebx]
						add		edi,_hModule
						mov		esi,_lpszApi
						mov		ecx,@dwStringLength
						repz	cmpsb					;比较esi和edi指向的内容,如果相同就将EDI指向后面一个单位继续比较,单位为一个字节,ECX中存放要比较的字符长度,存在不相同的就停止并设置zf标志位为0
						.if		ZERO?
								pop		esi
								jmp		@F
						.endif
						pop		esi
						add		ebx,4
						inc		edx
				.until	edx >= [esi].NumberOfNames
				jmp		_Error
@@:
;*********************************************************************************************************************
;API名称索引-->序号索引-->地址索引
;*********************************************************************************************************************
				sub		ebx,[esi].AddressOfNames
				sub		ebx,_hModule
				shr		ebx,1
				add		ebx,[esi].AddressOfNameOrdinals		
				add		ebx,_hModule
				movzx	eax,word ptr [ebx]					;获得序号索引
				shl		eax,2
				add		eax,[esi].AddressOfFunctions
				add		eax,_hModule						;获得地址
;************************************************************************************************************************
;从地址表得到导出函数的位置
;************************************************************************************************************************
				mov		eax,[eax]					;得到指向函数地址的RVA
				add		eax,_hModule
				mov		@dwReturn,eax
_Error:
				pop		fs:[0]						;恢复原来的SEH链
				add		esp,0ch
				assume	esi:nothing
				popad
				mov		eax,@dwReturn
				ret
				
_GetApi			endp

在查找Kernel32.dll基址的时候,我们将参数(也就是一个位于Kernel32.dll中的一个地址)的低位清0,因为我们要按照64KB的大小来寻找。

当我们找到Kernel32.dll基址后,就可以通过这个基址定位到PE文件头中的IMAGE_OPTIONAL_HRADER32结构的数据目录表的基址,然后再通过数据目录找到导出表的位置,最后再通过函数名找到函数在导出函数序号表中的索引,然后获取函数的序号,最后获取到函数的真正入口地址。

可以写一个程序来验证一下:
 

				.386
				.model	flat,stdcall
				option	casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include			windows.inc 
_ProtoGetProcAddress	typedef proto	:dword, :dword
_ProtoLoadLibrary		typedef	proto	:dword
_ProtoMessageBox		typedef	proto	:dword, :dword, :dword, :dword
_ApiGetProcAddress		typedef	ptr		_ProtoGetProcAddress
_ApiLoadLibrary			typedef	ptr		_ProtoLoadLibrary
_ApiMessageBox			typedef	ptr		_ProtoMessageBox
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				.data?
hDllKernel32	dd		?
hDllUser32		dd		?
_GetProcAddress	_ApiGetProcAddress		?
_LoadLibrary	_ApiLoadLibrary			?
_MessageBox		_ApiMessageBox			?

				.const
szLoadLibrary	db		'LoadLibraryA',0
szGetProcAddress db		'GetProcAddress',0
szUser32		db		'user32',0
szMessageBox	db		'MessageBoxA',0
szCaption		db		'A MessageBox !',0
szText			db		'Hello, Win32 ASM !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
				.code
include			_GetKernel.asm
start:
;******************************************************************************************************************
;从堆栈中的Ret地址找到Kernel32.dll的基地址,并在Kernel32.dll
;的导出表中查找GetProcAddress函数的入口地址
;******************************************************************************************************************
				invoke	_GetKernelBase,[esp]				;此时ESP所指的地址在Kernel32.dll中
				.if		eax
						mov		hDllKernel32,eax
						invoke	_GetApi,hDllKernel32,addr szGetProcAddress			;得到GetProcAddress函数的入口地址
						mov		_GetProcAddress,eax
				.endif
;******************************************************************************************************************
;用得到的GetProcAddress函数得到LoadLibrary函数地址并装入其他DLL
;******************************************************************************************************************
				.if		_GetProcAddress
						invoke	_GetProcAddress,hDllKernel32,addr szLoadLibrary
						mov		_LoadLibrary,eax
						.if		eax
								invoke	_LoadLibrary,addr szUser32
								mov		hDllUser32,eax
								invoke	_GetProcAddress,hDllUser32,addr szMessageBox
								mov		_MessageBox,eax
						.endif
				.endif
				.if		_MessageBox
						invoke	_MessageBox,NULL,offset szText,offset szCaption,MB_OK
				.endif
				ret
			
end				start
						
				

程序先调用 _GetKernelBase函数获取kernel32.dll的基址,然后再调用_GetApi获取GetProcAddress函数的入口地址,然后通过GetProcAddress函数我们可以获得LoadLibrary函数的地址,这样我们就可以轻松得到我们想要的函数和DLL的地址了,当然我们要方便一点用这些获取的函数的话,要像这个程序一样在最前面要声明函数原型。

程序编译链接后运行:

可以正确显示窗口,那么证明这样做是可以的。我们可以再用之前的查看导入表的程序查看这个程序:

 可以看到这个函数里面没有任何导入函数,全都是我们自己导入的。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态获取API的地址 的相关文章

  • 【攻防世界】web新手练习002 robots

    攻防世界 web新手练习002 robots 难度系数 xff1a 1 题目描述 xff1a X老师上课讲了Robots协议 xff0c 小宁同学却上课打了瞌睡 xff0c 赶紧来教教小宁Robots协议是什么吧 题目场景 xff1a ht
  • 【攻防世界】web新手练习003 backup

    攻防世界 web新手练习003 backup 难度系数 xff1a 1 题目描述 xff1a X老师忘记删除备份文件 xff0c 他派小宁同学去把备份文件找出来 一起来帮小宁同学吧 xff01 题目场景 xff1a http 111 200
  • 【攻防世界】web新手练习004 cookie

    攻防世界 web新手练习004 cookie 难度系数 xff1a 1 题目描述 xff1a X老师告诉小宁他在cookie里放了些东西 xff0c 小宁疑惑地想 xff1a 这是夹心饼干的意思吗 xff1f 题目场景 xff1a http
  • 【攻防世界】web新手练习005 disabled_button

    攻防世界 web新手练习005 disabled button 难度系数 xff1a 1 题目描述 xff1a X老师今天上课讲了前端知识 xff0c 然后给了大家一个不能按的按钮 xff0c 小宁惊奇地发现这个按钮按不下去 xff0c 到
  • C语言将十进制整数输出为八进制和十六进制

    方法一 xff1a 直接使用控制字符串 o 八进制 x X 十六进制 方法二 xff1a 函数 char itoa int value char string int radix 返回值类型char 参数value 待转换的数字 参数str
  • WebShell --冰蝎

    文章目录 一 介绍二 下载安装三 使用四 缺点 本文章仅作于研究学习 xff0c 禁止用于非法用途 xff01 一 介绍 Webshell管理工具 xff0c 动态二进制加密网站客户端 流量动态加密 xff0c 攻击特征安全设备 xff08
  • 【攻防世界】web新手练习006 weak_auth

    攻防世界 web新手练习006 weak auth 难度系数 xff1a 1 题目描述 xff1a 小宁写了一个登陆验证页面 xff0c 随手就设了一个密码 题目场景 xff1a http 111 200 241 244 55583 解题思
  • 【攻防世界】web新手练习007 simple_php

    攻防世界 web新手练习007 simple php 难度系数 xff1a 1 题目描述 xff1a 小宁听说php是最好的语言 于是她简单学习之后写了几行php代码 题目场景 xff1a http 111 200 241 244 5583
  • 【攻防世界】web新手练习008 get_post

    攻防世界 web新手练习008 get post 难度系数 xff1a 2 题目描述 xff1a X老师告诉小宁同学HTTP通常使用两种请求方法 xff0c 你知道是哪两种吗 xff1f 题目场景 xff1a http 111 200 24
  • 【攻防世界】web新手练习010 webshell

    攻防世界 web新手练习010 webshell 难度系数 xff1a 2 题目描述 xff1a 小宁百度了php一句话 觉着很有意思 并且把它放在index php里 题目场景 xff1a http 111 200 241 244 635
  • 【攻防世界】web新手练习011 command_execution

    攻防世界 web新手练习011 command execution 难度系数 xff1a 2 题目描述 xff1a 小宁写了个ping功能 但没有写waf X老师告诉她这是非常危险的 xff0c 你知道为什么吗 题目场景 xff1a htt
  • 【攻防世界】web新手练习012 simple_js

    攻防世界 web新手练习012 simple js 难度系数 xff1a 2 题目描述 xff1a 小宁发现了一个网页 xff0c 但却一直输不对密码 Flag格式为 Cyberpeace xxxxxxxxx 题目场景 xff1a http
  • 【已解决】Eclipse启动后从console跳转到server

    已解决 Eclipse启动后从console跳转到server 运行环境 xff1a win10专业版 Eclipse2021 问题描述 从Eclipse中启动tomcat之后 xff0c 原本从console显示日志 xff0c 但是日志
  • 【已解决】Eclipse 创建Maven项目Select an Archetype为空解决方法

    已解决 Eclipse 创建Maven项目Select an Archetype为空解决方法 运行环境 xff1a win10专业版 Eclipse2021 maven 3 5 问题描述 使用Eclipse创建maven项目在选择模板时 x
  • 【已解决】Eclipse Run Sever 打开tomcat报错Not found404

    已解决 Eclipse Run Sever 打开tomcat报错Not found404 运行环境 xff1a win10专业版 Eclipse 2020 Tomcat 8 5 7 1 问题描述 刚刚安装好一个eclipse 配置完成之后
  • Pycharm打包python文件为exe格式

    Pycharm打包python文件为exe格式 运行环境 xff1a win10专业版 Python 3 9 1 将需要打包的内容单独放在一个文件 2 创建一个虚拟环境 打包出来的体积相对小很多 新建一个虚拟环境 在终端中执行下列代码 py
  • 中兴B860AV2.1-T刷机教程加固件

    第一步 xff1a 拆开中兴B860AV2 1 T盒子 xff0c 取出主板 第二步 xff1a 下载刷机工具Amlogic USB Burning Tool v2 1 6 8 下载工具 xff1a 链接 xff1a https downl
  • Python输出系统信息(操作系统、版本号等)

    Python输出操作系统信息 xff08 操作系统 版本号等 xff09 运行环境 xff1a win10专业版 Python 3 9 Pycharm 社区版 1 使用platform 模块获取系统信息 span class token k
  • 【已解决】win7 32位操作系统使用pyinstaller打包exe可执行文件文件

    已解决 win7 32位操作系统使用pyinstaller打包exe可执行文件文件 运行环境 xff1a win7 32位旗舰版 Python 3 6 8 问题描述 xff1a 近期我在win10 64位的python3 9环境上写了一个e
  • 第九章 vue 进阶篇 Element Plus 基本使用

    Element Plus 基本使用 element ui 是基于vue 开发的一套ui组件库 xff0c 提供丰富的网页开发组件 xff0c 可用快速开发网站 xff0c 降低前端开发成本 版本 element目前有两个版本 element

随机推荐

  • 【物联家居】第二章:服务器--玩客云刷入armbian系统,作为数据交互中心

    日记 xff1a 现在是2021年6月12日 14 07 18 物联家居 总目录 目录 一 玩客云 二 需要材料 三 刷入Armbian 步骤一 xff1a 刷底包 步骤二 xff1a 把armbian固件写入U盘 xff08 同sd卡 x
  • C# 实现RDP远程桌面连接

    C 实现RDP远程桌面连接 因为频繁的访问远程windows server服务器 xff0c 每次调出cmd运行mstsc xff0c 然后输入一大串信息去链接就显得有些繁琐了 为方便计 xff0c 于是使用C 编写一个小工具 功能相当简陋
  • 单片机小白学习之路(十七)---计算初值

    目标 xff1a 学会计算初值 1 为什么要初值 xff1f 给单片机的定时器赋初值是为了取得准确的自己需要的定时时间 xff0c 比如我想定时100秒 xff0c 你数0 255要256秒 xff08 最大定时长 xff09 xff0c
  • hadoop-hdfs初学之基本常用命令的IDEA实现

    刚开始学hadoop xff0c 大家一起加油 xff0c 再接再厉 span class token keyword package span span class token namespace com span class token
  • ubuntu20.04卸载virtualbox失败,“if your system is using efi secure boot you may need to sign the kernel “

    ubuntu20 04卸载virtualbox失败 xff0c 报错信息中有 if your system is using efi secure boot you may need to sign the kernel modules v
  • [算法]马走日

    题目描述 xff1a 在国际象棋中 xff0c 马的走法与中国象棋类似 xff0c 即俗话说的 马走日 xff0c 下图所示即国际象棋中马每一步能到达的格子 xff08 箭头所指为每步到达位置 xff09 现有一200 200大小的国际象棋
  • 咪咕盒子MGV2000电视盒子刷机教程

    第一步 xff1a 使用U盘里面新建文件夹重命名为 xff1a upgrade 第二步 xff1a 下载更新包放到uprade文件夹内 xff0c 下载地址 xff1a https download csdn net download cy
  • edge浏览器配置跨域完整流程-前端

    edge浏览器配置跨域完整流程 前端 1 在D盘下创建 edgeFile 新文件夹 2 进入edge文件位置 复制自己的edge 名字就叫dev 可以随便取 3 右键选中dev点击属性 配置edge的目标路径 C Program Files
  • oracle11g无法导出空表问题

    产生原因 xff1a oracle11g为了节约空间 xff0c 对空表不分配segment 解决方法 方法1 用如下语句设置空表可导出 xff1a alter system set deferred segment creation 61
  • 将dwg文件转为shp文件

    将dwg文件转为shp文件 xff08 包括dwg的注记转换 xff09 目的 xff1a 利用ArcGIS软件 将dwg文件中的面状要素转为shp格式 xff0c 并将dwg中的注记转换成shp文件中的字段 方法一 xff1a 1 将dw
  • ArcGIS坐标转换

    地理坐标系 xff1a 常用的地理坐标系 xff1a WGS84坐标系 CGCS2000坐标系 北京54坐标系 西安80坐标系 地理坐标系是是球面坐标系统 xff0c 通过经度 纬度 对地球表面点进行说明 不同地理坐标系的主要区别在于其采用
  • arcmap字段计算器的使用

    需求1 xff1a 某个要素类中的某个字段的数据前有空格 xff0c 需将空格批量删除 解决方法 xff1a 打开arcmap xff0c 添加图层 xff0c 选择开始编辑 xff08 如下图 xff09 选中图层 xff0c 右键打开属
  • ArcMap 数据的标注和注记

    标注 xff1a 可按照当前地图比例尺下的最佳位置重新加载 注记 xff1a 每条注记都存储自身的位置 注记可由标注转化而来 本文包括几种基本的标注方法 包括多属性字段标注 分类标注 分数型标注 道路名称标注等 多个属性字段标注 如下图 x
  • ArcMap 矢量数据空间校正

    功能 xff1a 将存在偏移 误差的数据进行校正 本文包括图形位移校正 橡皮拉伸 接边的操作方法 情况1 xff1a 两图层存在位置偏移 xff0c 现需校正其中一个数据 xff0c 使两个数据完全重合 Arcmap中放入两个数据 xff0
  • 【oracle报错】 exp-00106数据链接口令无效

    问题 xff1a 用exp导出数据库中的data 1表 xff0c 报错 exp 00106数据链接口令无效 xff0c 但其他表可正常导出 分析 xff1a 与无效dblink有关 解决过程 xff1a 用查询语句 select from
  • ARCGIS安装及卸载中遇见的一些问题

    1 提示无 netframework3 5 注意 xff1a 缺少 netframework3 5 安装4 5依旧无法安装arccgis desktop 解决方法 xff1a 计算机单击右键选择 管理 xff0c 在 服务管理器 中选择 添
  • ora-00972标识符过长

    ora 00972标识符过长 可能原因 xff1a Oracle中表名 xff0c 列名 xff0c 标识列字符不能超过30个字符 但我是利用plsql导入csv格式数据时 xff0c 报错ora 00972 xff0c 表是之前建好的 x
  • Ubuntu切换内地源

    编辑 etc apt sources list删除里面的所有内容添加以下内容到sources中保存即可 阿里云源 deb http mirrors aliyun com ubuntu focal main restricted univer
  • oracle 用exp导出表

    用于导出oracle数据库表空间的表 xff0c 有以下几种情况 一般导出 xff1a exp username password 64 ip地址 实例 file 61 路径及文件名 导出表空间指定的表 exp username passw
  • 动态获取API的地址

    原理 xff1a 现在虽然大部分Win32程序都使用ExitProcess函数来终止执行 xff0c 但是其实用ret指令也是可以的 我们的应用程序的主程序可以被看成是一个被Windows调用的子程序 当父进程要创建一个子进程时 xff0c