社区
C语言
帖子详情
能定位修改代码后被影响的二进制文件吗?
happyhuang
2008-05-21 08:39:17
困扰我许久的问题。
背景是需要给一个很大的系统作补丁,最后提供的就是几个需要重新覆盖安装的二进制文件。
比如,string.cpp里面的strcat()函数被修改了,那么所有调用strcat()的库文件、可执行文件都需要提供给客户。
而所有仅仅调用strcpy()函数的那些库文件都不需要提供。
现在的办法是在浩如烟海的代码和Makefile中寻找被影响的文件,但是效率太低而且太容易出错了。
大家有什么好办法吗?
...全文
223
23
打赏
收藏
能定位修改代码后被影响的二进制文件吗?
困扰我许久的问题。 背景是需要给一个很大的系统作补丁,最后提供的就是几个需要重新覆盖安装的二进制文件。 比如,string.cpp里面的strcat()函数被修改了,那么所有调用strcat()的库文件、可执行文件都需要提供给客户。 而所有仅仅调用strcpy()函数的那些库文件都不需要提供。 现在的办法是在浩如烟海的代码和Makefile中寻找被影响的文件,但是效率太低而且太容易出错了。 大家有什么好办法吗?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
23 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
fuqd273
2008-05-22
打赏
举报
回复
[Quote=引用 22 楼 happyhuang 的回复:]
我原来也是这么觉得的,后来发现所有动态链接的目标文件都有时间更新,而我们只需要提供其中的动态链接库即可。
比如楼上举的例子:
cc -o test test.c -L/etc/lib/stdlib -lmylab
make会在两种情况下重新编译产生test目标文件。
1、test.c发生了改动
2、libmylab.so发生了改动
第二种情况,如果只…
[/Quote]
建议:
1、整体发布的情况:按照现有流程,但是最好是自动化实现,即、由顶层makefile实现批处理
2、差分发布的情况(也就是你需要的这种情况):在生成mylab的时候,不要在-L/etc/lib/stdlib 处产生最新的libmylab.so/libmylab.lib。这是可以做到的、例如,采用通过环境变量控制流程的条件编译。这样,在编译test.c的时候,就不会因为libmylab.so变化而更新了。
另:从你给出的makefile来看,已经有统一的lib管理路径,只需要略加修正就可以了。
happyhuang
2008-05-22
打赏
举报
回复
[Quote=引用 21 楼 coding_hello 的回复:]
奇怪,MakeFile不就是干这活的吗? 把编译后的时间更新的挑出来不就完了
[/Quote]
我原来也是这么觉得的,后来发现所有动态链接的目标文件都有时间更新,而我们只需要提供其中的动态链接库即可。
比如楼上举的例子:
cc -o test test.c -L/etc/lib/stdlib -lmylab
make会在两种情况下重新编译产生test目标文件。
1、test.c发生了改动
2、libmylab.so发生了改动
第二种情况,如果只是libmylab.so发生了改动,那么需要提供给用户的补丁只需要libmylab.so,而不需要提供test(因为是动态链接,接口不变的话,test不受影响),但是两个目标文件test和libmylab.so的时间都被更新了。
现在最大的问题就是如何通过脚本剔除这些动态链接库。
难道要我们去解析Makefile吗?还是能通过对目标文件执行某些命令就能发现哪些库是动态链接的?
野男孩
2008-05-22
打赏
举报
回复
奇怪,MakeFile不就是干这活的吗? 把编译后的时间更新的挑出来不就完了
boyzhang
2008-05-22
打赏
举报
回复
用特征码试试,和VC的增量编译差不多.
以前自己写的一个嵌入式系统的源代码,发给客户了,
过了很长时间,说要改,源代码不知道放到那里去了,
只是改几个界面的上文字,于是,就用WinHex直接写二进制改的,
建议你也可以把修改过的函数的特征码找出来,自己做个二进制
特征码搜索工具,把调用了该函数的文件都更新一下就行了.
fuqd273
2008-05-21
打赏
举报
回复
如果是静态连接……
抱歉,我没有更好的办法。
全部重新编译系统恐怕是最快的、最便捷的方法了。
fuqd273
2008-05-21
打赏
举报
回复
印象中lyricEdit.lib 里面只是提供了函数名和参数?
真正的函数指针是libstring.so提供的。
换言之,除非修改了函数接口(简单地说,就是连头文件的声明都发生了变化的情况),lib文件不需要替换。
而函数实体发生变化的话,对应的so文件需要全部更新。
否则……封装成动态库还有什么意义么?
fuqd273
2008-05-21
打赏
举报
回复
lyricEdit.lib 需要提供么?
你采取了需要修正lyricEdit.lib 的修改方法?
happyhuang
2008-05-21
打赏
举报
回复
-------------------- 代码
///// string.cpp
string::diskSave()
{
cout<<"Save to disk"<<endl;
}
string::show()
{
cout<<"Show string"<<endl;
}
///// lyricEdit.cpp
lyric::edit()
{
string a;
a.show();
a.edit();
a.diskSave(); /// <------ 调用
}
////// lyricShow.cpp
lyric::show()
{
string a;
a.show();
}
-------------------- Makefile
gcc string.cpp -shared -o libstring.so
gcc lyricEdit.cpp -lstring -o lyricEdit.lib
gcc lyricShow.cpp -lstring -o lyricShow.lib
-------------------- 修改
string::diskSave()
{
/// cout<<"Save to disk"<<endl;
cout<<"function changed!"<<endl;
}
修改之后
1. 需要向用户提供的补丁文件就是libstring.so和lyricEdit.lib
2. lyricShow.lib不需要提供,因为他没有调用diskSave()函数
不知道这样说清楚了吗?
我的问题是
3. 除了通读代码之外,有什么更好的办法能自动找出需要提供的补丁文件吗(lyricEdit.lib)?
以上3点,有哪一点看不明白,请指出,谢谢。
babyvox1999
2008-05-21
打赏
举报
回复
我们很容易知道string::diskSave()修改了之后string.lib需要重新安装。可是要如何去寻找lyricEdit.lib呢?尤其是整个系统有成百上千个lib文件的时候。
========================================================
不明白什么意思
happyhuang
2008-05-21
打赏
举报
回复
举个例子,假设我们的产品是MediaPlayer,其中包含了如下库文件和歌词:
decode.lib 音频解码
lyricShow.lib 显示歌词
lyricEdit.lib 歌词编辑器
help.lib 帮助,出错信息提示
string.lib string::show()
string::diskSave()
调用关系是
lyricShow.lib ----> string::show()
lyricEdit.lib -+--> string::show()
|
+--> string::diskSave()
help.lib ---------> string::show()
现在string.lib里面的string::diskSave()函数发现了bug,并已经改好了。需要提供的补丁安装包将包含两个二进制文件:lyricEdit.lib和string.lib
我们很容易知道string::diskSave()修改了之后string.lib需要重新安装。可是要如何去寻找lyricEdit.lib呢?尤其是整个系统有成百上千个lib文件的时候。
WingForce
2008-05-21
打赏
举报
回复
不是有所谓的动态链接技术么。。。
happyhuang
2008-05-21
打赏
举报
回复
[Quote=引用 16 楼 fuqd273 的回复:]
所以我列举了2种情况啊。
用shell脚本不能把筛选出来1的那部分筛选出来么?
首先找到所有的变更文件,然后去掉不是由于代码变动、而是由于链接库变动而生成的目标文件。不就OK了么?
[/Quote]
挺清楚的,谢谢。接下来的问题恐怕是要怎么把1的情况筛选出来。
我把我工作中碰到的实际情况贴上来吧。
-----------------------------------------------------------
1、我修改了一个协议处理的源文件:
/projects/ESPN/source/Protocol/Msg/v32/protocol.cpp
-----------------------------------------------------------
2、该目录下的Makefile定义了怎样去编译这个源文件:
# 机器类型4254
MSGVAR32GEN_E4254A_OBJECTS = $(MSGVAR32GEN_HPUX32_OBJECTS:$(SDB_PA32HPUX_SF).o=$(SDB_E4254A_SF).o) \
$(addprefix $(MSGVAR32GEN)/$(DERIVEDOBJS)/, \
ProtocolPP_$(SDB_E4254A_SF).o \
Protocol_$(SDB_E4254A_SF).o )
# 机器类型6741
MSGVAR32GEN_J6741A_OBJECTS = $(MSGVAR32GEN_E4254A_OBJECTS:$(SDB_E4254A_SF).o=$(SDB_J6741A_SF).o)
# 机器类型7557
MSGVAR32GEN_E7557A_OBJECTS = $(MSGVAR32GEN_E4254A_OBJECTS:$(SDB_E4254A_SF).o=$(SDB_E7557A_SF).o)
-----------------------------------------------------------
3、要提供的库在这里找到
/projects/ESPN/source/Protocol/IfpcLib/Makefile
# 机器类型6741
SDBPROTOCOL_IFPCLIB_J6741A_OBJECTS = $(SDBPROTOCOL_COM_J6741A_OBJECTS) \
$(BUFFERPLUS_CORE_J6741A_OBJECTS) \
$(BUFFERPLUS_P7_PAP_J6741A_OBJECTS) \
$(PAPINT_COM_J6741A_OBJECTS) \
$(PAPINT_V29_J6741A_OBJECTS) \
$(PAPINT_V30_J6741A_OBJECTS) \
$(PAPINT_V32_J6741A_OBJECTS) \
$(PAPINT_V34_J6741A_OBJECTS) \
$(MSGVAR29_J6741A_OBJECTS) \
$(MSGVAR30_J6741A_OBJECTS) \
$(MSGVAR32GEN_J6741A_OBJECTS) \
$(MSGVAR34_J6741A_OBJECTS)
SDBPROTOCOL_IFPCLIB_J6741A_LIBS = $(SDB_ZLIB_BPP_LIB_DIR)/libz.a
SDBPROTOCOL_IFPCLIB_J6741A_TARGET = $(SDBPROTOCOL_IFPCLIB_E4254A_TARGET:$(SDB_E4254A_SF).sl=$(SDB_J6741A_SF).sl)
$(SDBPROTOCOL_IFPCLIB_J6741A_TARGET) : $(SDBPROTOCOL_IFPCLIB_J6741A_OBJECTS) \
$(SDBPROTOCOL_IFPCLIB_J6741A_LIBS)
-----------------------------------------------------------
我的工作流程:
1、把源文件protocol.cpp改好
2、在当前目录下的Makefile里面找对应的.o文件是怎么编译的,找到宏定义MSGVAR32GEN_E4254A_OBJECTS...
3、grep所有目录下的所有Makefile,找MSGVAR32GEN_E4254A_OBJECTS...
终于找到在/projects/ESPN/source/Protocol/IfpcLib/中,有一个J6741A_TARGET引用了这个object文件,于是这个目标文件需要提供给客户。
如果我每改一个源文件就要这样,效率太低了。
如果用你建议的方法,不知道要怎么把情况1筛选出来呢?
fuqd273
2008-05-21
打赏
举报
回复
或者——
所有的makefile增加switch开关,
在指定情况下,不更新install目录下的so/lib。
fuqd273
2008-05-21
打赏
举报
回复
不明白既然已经离目的地那么近了,还在兜圈子……
fuqd273
2008-05-21
打赏
举报
回复
[Quote=引用 15 楼 happyhuang 的回复:]
如果只是libmylab.so发生了改动,那么需要提供给用户的补丁是libmylab.so,而不需要提供test(因为是动态链接)
但是现在make会重新生成新的test目标文件。
所以,通过脚本判断make生成的目标文件新旧,是不足以区分出需要提供给用户的补丁的。[/Quote]
所以我列举了2种情况啊。
用shell脚本不能把筛选出来1的那部分筛选出来么?
首先找到所有的变更文件,然后去掉不是由于代码变动、而是由于链接库变动而生成的目标文件。不就OK了么?
happyhuang
2008-05-21
打赏
举报
回复
[Quote=引用 13 楼 fuqd273 的回复:]
例如:
cc -o test test.c -L/etc/lib/stdlib -lmylab
make会在两种情况下重新编译产生test目标文件。
1、test.c发生了改动
2、libmylab.so发生了改动
够清楚了么?
[/Quote]
如果只是libmylab.so发生了改动,那么需要提供给用户的补丁是libmylab.so,而不需要提供test(因为是动态链接)
但是现在make会重新生成新的test目标文件。
所以,通过脚本判断make生成的目标文件新旧,是不足以区分出需要提供给用户的补丁的。
fuqd273
2008-05-21
打赏
举报
回复
[Quote=引用 12 楼 happyhuang 的回复:]
比如这种情况:一个头文件里声明了两个类,class a增加了函数;class b没有动,所有include这个头文件的so库都要重新编译。可是实际上应该只是用class a的so库才真正受到了影响。[/Quote]
你确定只有用到class a 的程序才受到影响?
参照了class b的程序不受影响么?
你真的确定?
fuqd273
2008-05-21
打赏
举报
回复
例如:
cc -o test test.c -L/etc/lib/stdlib -lmylab
make会在两种情况下重新编译产生test目标文件。
1、test.c发生了改动
2、libmylab.so发生了改动
够清楚了么?
happyhuang
2008-05-21
打赏
举报
回复
[Quote=引用 10 楼 fuqd273 的回复:]
make本身提供自动查询最新目标文件的功能。
换言之,既然已知是很复杂的大型项目,不理解为什么不采用整体makefile进行统一编译的方式。
采用父makefile调用子makefile的形式更新so库。
[/Quote]
> 1. 关于make的查询最新目标文件
比如这种情况:一个头文件里声明了两个类,class a增加了函数;class b没有动,所有include这个头文件的so库都要重新编译。可是实际上应该只是用class a的so库才真正受到了影响。
> 2. 采用父makefile调用子makefile的形式更新so库
我们的系统是这样设计的。只是不知道面对这些父makefile和子makefile,要怎么去找真正受影响的so库呢?
fuqd273
2008-05-21
打赏
举报
回复
如果说,你的问题是,将混杂在一起的最新版本目标文件与旧版本目标文件区分开。
方法之一:shell编程
楼下继续。
加载更多回复(3)
libshelf:elf
文件
格式的实用程序
架子 书架是对ERESI逆向工程软件界面中一些选择工具的简单替代尝试。 它旨在提供用于操作ELF
二进制
文件
的可编写脚本或进行交互的界面。 它主要用于减轻ELF
二进制
文件
(可执行
文件
,共享对象,核心转储和可重
定位
对象)的静态和运行时
修改
的麻烦。 一些计划的功能包括: 注入共享库和可重
定位
的目标
代码
。 函数挂钩/重定向的几种形式,包括plt注入,DT_DEBUG到DT_NEEDED转换,函数蹦床和.ctor / .dtor覆盖。 提供类似于shell的界面,用于检查和
修改
ELF
二进制
文件
。 将提供对ELF
文件
中任何数据结构的完全读/写访问权限。 静态和动态ELF
文件
重新链接。 常见的ELF感染技术(例如Silvio .text padding感染)的自动化。 为带有部分节表重建的剥离
二进制
文件
提供GNU readelf和objdump的替代方案。
【GDB】
修改
程序的
二进制
文件
背景介绍 GDB不仅可以用来调试程序,还可以直接
修改
被调试程序的
二进制
文件
。这种方式相比于改源码重新编译、gdb attach有什么优势呢?考虑以下企业生产环境中的几个调试场景: 需要
修改
的
二进制
文件
是其他领域的,你没有源码和编译工程,让相关领域出调试对接件比较费时,但你只想临时改一行别人的
代码
,几分钟内完成验证。 调试环境上,使用gdb attach进程方式有困难: 被调试的服务(进程)没有启动断点(可
定位
性很差),或者gdb手动拉起的方法非常复杂,等服务正常启动后再attach已经赶不上打断点的时机
chatgpt赋能python:Python
文件
编译为
二进制
文件
编译是将源
代码
转换为机器可执行
代码
的过程。当Python
代码
被编译为
二进制
文件
时,它的机器码可以直接由操作系统执行,无需通过解释器解释。这可以极大提高Python
代码
的执行效率,并且也更容易地保护Python
代码
。Python提供了两种方式将Python
文件
编译为
二进制
文件
。第一种方式是使用Python自带的 py_compile 模块,第二种方式是使用第三方库 cx_Freeze。本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的
修改
。以上只是chatgpt能力的冰山一角。
【C语言初阶】[图文]
二进制
文件
怎么看?C语言能对
文件
进行哪些操作?今天我来教你
二进制
文件
怎么看?C语言能对
文件
进行哪些操作?这篇文章能帮到你
C++操作
二进制
文件
二进制
文件
不是以ASCII
代码
存放数据的,它将内存中数据存储形式不加转换地传送到磁盘
文件
,因此它又称为内存数据的映像
文件
。因为
文件
中的信息不是字符数据,而是字节中的
二进制
形式的信息,因此它又称为字节
文件
。 对
二进制
文件
的操作也需要先打开
文件
,用完后要关闭
文件
。在打开时要用ios::binary指定为以
二进制
形式传送和存储。
二进制
文件
除了可以作为输入
文件
或输出
文件
外,还可以是既能输入又能输出的
C语言
69,371
社区成员
243,080
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章