恢复数据库记录源代码:
import os.path
dbfilename="test.db"
f=file(dbfilename, "rb")
fout=file("out.db", "wb")
def readpage(f,ind):
f.seek(ind*0x400)
return f.read(0x400)
def recover(dat):
lenmap={}
cleanpos=ord(dat[1])*0x100+ord(dat[2])
if cleanpos==0: return dat
newdat = bytearray(dat)
newdat[1]=0
newdat[2]=0
recovnode=[]
while cleanpos!=0:
nextpos=ord(dat[cleanpos])*0x100+ord(dat[cleanpos+1])
datlen=ord(dat[cleanpos+3])
for n in xrange(4,datlen):
if dat[cleanpos+n]==dat[cleanpos] and dat[cleanpos+n+1]==dat[cleanpos+1]:
nextpos=cleanpos+n
datlen=nextpos-cleanpos
break
recovnode.append(cleanpos)
lenmap[cleanpos]=datlen
newdat[cleanpos]=datlen
newdat[cleanpos+1]=0
newdat[cleanpos+2]=newdat[cleanpos]-4
newdat[cleanpos+2]=0
cleanpos=nextpos
reccnt=ord(dat[3])*0x100+ord(dat[4])
recstart=ord(dat[5])*0x100+ord(dat[6])
for i in xrange(0,reccnt):
datpos=ord(dat[8+2*i])*0x100+ord(dat[9+2*i])
lenmap[datpos]=ord(dat[datpos])+2
recovnode.append(datpos)
firstrec=ord(dat[8+2*reccnt])*0x100+ord(dat[9+2*reccnt])
cleanpos=firstrec
while cleanpos!=0 and cleanpos<0x400:
if cleanpos in recovnode:
cleanpos+=lenmap[cleanpos]
continue
nextpos=cleanpos+ord(dat[cleanpos+2])*0x100+ord(dat[cleanpos+3])
lenmap[cleanpos]=ord(dat[cleanpos+3])
recovnode.append(cleanpos)
newdat[cleanpos]=ord(dat[cleanpos+3])-2
cleanpos=nextpos
recovnode.sort()
recovnode.reverse()
idcnt=0
newdat[3]=len(recovnode)>>8
newdat[4]=len(recovnode)&0xff
newdat[5]=recovnode[-1]>>8
newdat[6]=recovnode[-1]&0xff
for node in recovnode:
newdat[8+2*idcnt]=node>>8
newdat[9+2*idcnt]=node&0xff
idcnt+=1
newdat[node]=lenmap[node]-2
newdat[node+1]=idcnt
newdat[node+2]=4
newdat[node+3]=0
return newdat
dat=readpage(f, 0)
fout.write(dat)
for ind in xrange(1, os.path.getsize(dbfilename)/0x400):
dat=readpage(f, ind)
fout.write(recover(dat))
实验步骤:
D:\lzf\dbrecover>sqlite3 test.db
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .echo on
sqlite> .read test.sql
.read test.sql
CREATE TABLE test (_id INTEGER PRIMARY KEY AUTOINCREMENT, nameid Integer, name text);
INSERT INTO test (nameid, name) VALUES (1, "lzf");
INSERT INTO test (nameid, name) VALUES (2, "luozf");
INSERT INTO test (nameid, name) VALUES (3, "lzhif");
INSERT INTO test (nameid, name) VALUES (4, "lzfan");
INSERT INTO test (nameid, name) VALUES (5, "l");
INSERT INTO test (nameid, name) VALUES (6, "zephyrluo");
INSERT INTO test (nameid, name) VALUES (7, "2B");
DELETE FROM test WHERE nameid=1 OR nameid=3 OR nameid=7 OR nameid=4 or nameid=2;
sqlite> select * from test;
select * from test;
5|5|l
6|6|zephyrluo
sqlite> .exit
.exit
D:\lzf\dbrecover>recovery.py
D:\lzf\dbrecover>sqlite3 out.db
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from test;
1|1|lzf
2|2|luozf
3|3|lzhif
4|4|lzfan
5|5|l
6|6|zephyrluo
7|7|2B