惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
量子位
小众软件
小众软件
Microsoft Azure Blog
Microsoft Azure Blog
V
Visual Studio Blog
I
InfoQ
Jina AI
Jina AI
The Cloudflare Blog
Recorded Future
Recorded Future
Recent Announcements
Recent Announcements
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
阮一峰的网络日志
阮一峰的网络日志
Microsoft Security Blog
Microsoft Security Blog
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Martin Fowler
Martin Fowler
T
Tailwind CSS Blog
博客园 - Franky
酷 壳 – CoolShell
酷 壳 – CoolShell
F
Fortinet All Blogs
WordPress大学
WordPress大学
P
Proofpoint News Feed
D
DataBreaches.Net
爱范儿
爱范儿
雷峰网
雷峰网
D
Docker
B
Blog
Engineering at Meta
Engineering at Meta
腾讯CDC
N
Netflix TechBlog - Medium
C
Check Point Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
T
Tenable Blog
GbyAI
GbyAI
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园 - 三生石上(FineUI控件)
T
The Blog of Author Tim Ferriss
博客园 - 聂微东
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
SecWiki News
SecWiki News
S
Security @ Cisco Blogs
S
Security Affairs
V
V2EX
Application and Cybersecurity Blog
Application and Cybersecurity Blog
云风的 BLOG
云风的 BLOG
C
CERT Recently Published Vulnerability Notes
Y
Y Combinator Blog

博客园 - 真 OO无双

(轉貼) Bit Twiddling Hacks (SOC) (Verilog) (C) (筆記) 如何移除VirtualBox所遺留下的驅動程式? (SOC) (VirtualBox) (筆記) always block內省略else所代表的電路 (SOC) (Verilog) (原創) 如何在Qsys Subsystem使用Interrupt? (SOC) (Nios II) (Qsys) (原創) Qsys或RTL做修改後,Nios II SBT該如何面對新的硬體? (SOC) (Nios II) (Qsys) (原創) 如何解決目錄改變時,Nios II project無法編譯的問題? (SOC) (Nios II) (DE2-70) (原創) Qsys Generation Tab的Simulation設定的意義 (SOC) (Nios II) (Qsys) (筆記) 如何寫入binary file某個byte連續n byte的值? (C/C++) (C) (筆記) 如何讀取binary file某個byte連續n byte的值? (C/C++) (C) (筆記) 如何讀取binary file某個byte的值? (C/C++) (C) (原創) Altera Technology Roadshow 2011 Taipei (SOC) (Quartus II) (Nios II) (Qsys) (原創) 如何在安裝SELinux的環境執行Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (筆記) 如何得知Quartus II最新版到底修改了哪些東西? (SOC) (Quartus II) (Nios II) (SOPC Builder) (Qsys) (筆記) Qsys resource整理 (SOC) (Nios II) (Qsys) (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox) (筆記) 如何在RedHat Linux安裝VirtualBox Guest Additions? (SOC) (Linux) (RedHat) (VirtualBox) (筆記) 常用設定暫存器值的編程技巧 (SOC) (C/C++) (C) (Verilog) (原創) Quartus II安裝新觀念:如何將Quartus II安裝在VirtualBox內? (SOC) (Quartus II) (VirtualBox) (筆記) $dispaly()、$strobe()、$monitor() 、$fwrite()與blocking / nonblocking的關係 (SOC) (Verilog) (Debussy) (Verdi)
(筆記) 如何寫入binary file某個byte的值? (C/C++) (C)
真 OO无双 · 2011-10-31 · via 博客园 - 真 OO无双

Abstract
通常公司為了保護其智慧財產權,會自己定義檔案格式,其header區會定義每個byte各代表某項資訊,所以常常需要直接對binary檔的某byte直接進行寫入。

Introduction
使用環境:Windows XP SP3 + Visual C++ 6.0 SP6

將在wf.bin的0x33 byte處寫入0xAC值。

WriteByte.c / C

 1 /* 
2 (C) OOMusou 2011 http://oomusou.cnblogs.com
3
4 Filename : WriteByte.c
5 Compiler : Visual C++ 6.0
6 Description : how to write byte value with n-byte position?
7 Release : oct.31,2011 1.0
8 */
9
10 #include <stdio.h>
11
12 int main() {
13 FILE *fp;
14 int filesize;
15 unsigned char buff[1];
16
17 fp = fopen("./wf.bin", "rb+");
18 if (!fp) {
19 fclose(fp);
20 return -1;
21 }
22
23 buff[0] = 0xAC;
24
25 fseek(fp, 0x33, SEEK_SET);
26 fwrite(buff, sizeof(unsigned char), 1, fp);
27
28 fclose(fp);
29
30 return 0;
31 }

17行

fp = fopen("./wf.bin", "rb+");

將wf.bin開啟,rb表示read binary,+表示除了read外,也可以做write。

23行

由於要寫入的是1個byte,其值為0xAC,故先宣告buff這個char array,將0xAC填入。

25行

fseek(fp, 0x33, SEEK_SET);

使用fseek將binary file的檔案位置移到0x33處,其中SEEK_SET表示offset是從檔頭開始。

26行

fwrite(buff, sizeof(unsigned char), 1, fp);

正式使用fwrite將buff寫入檔案。

完整程式碼下載
WriteByte.7z

Conclusion
以上的code看起來都很直觀,但讓我搞一天的地方是在17行,我原本以為既然是要寫入binary file,所以很直覺的這樣寫:

fp = fopen("./wf.bin", "wb");

wb表示write binary,看起來非常直覺,但結果卻會變成位置0x33處的確會寫入0xAC,但檔案卻到此為止,後面的資料完全不見了!!

為什麼會這樣呢?

在C IN A NUTSHELL語法暨程式庫標準辭典[1] p.208第7行:

如果模式字串以r開始,此檔案必須有存在檔案系統中才行。如果模式字串以w開始,那麼如果檔案不存在,就會建立一個新檔案;如果存在,那麼之前的內容就會遺失,因為在write中,fopen()函式會將檔案的長度截為0。

也就是說,因為使用wb開啟,且又使用fseek()移動了binary file的位置到0x33,所以0x33之後檔案長度被截為0,然後fwrite()將0xAC寫到檔案位置0x33處。

所以雖然只是小小的差異,但結果卻天差了十萬八千里啊。

在此筆記fopen()所有參數排列組合的意義[2]

r 打開現有text file以便讀取
w 生成新text file或截短現有text file至零長度以便寫入
a 附加。生成新text file或打開現有text file以便在文件結束處寫入
rb 打開現有binary file以便讀取
wb 生成新binary file或將現有binary file截至零長度以便寫入
ab 附加。生成新binary file或打開現有binary file以便在文件結束處寫入
r+ 打開現有text file,以便更新(讀和寫)
w+ 生成新text file或將現有text file截至零長度以便更新。
a+ 附加。生成新text file或打開現有text file以便更新,在文件結束處寫入
r+b或rb+ 打開現有binary file以便更新(讀和寫)
w+b或wb+ 生成新binary file或截短現有文件至零長度以便更新
a+b或ab+ 附加。生成新binary file或截短現有文件至零長度以便更新,在文件結束處寫入

See Also

(筆記) 如何寫入binary file某個byte連續n byte的值? (C/C++) (C)

Reference
[1] Peter Prinz & Tony Crawford 2005, 蔡學鏞 編譯,C IN A NUTSHELL語法暨程式庫標準辭典,美商歐萊禮股份有限公司

[2] P.J Plauger, The Standard C Library