|
1 | 1 | #!/usr/bin/env lua |
2 | 2 |
|
3 | | ---Set PE timestamps to a constant so builds are repeatable |
4 | | -C,E,I,S,V="cur","!EOF","<I4","set",809222400 |
5 | | -function R(l)local b=F:read(l)if b and#b>=l then return string.unpack(l==2 and"<I2"or I,b)end error(E)end |
6 | | -function W(p,v)F:seek(S,p)F:write(string.pack(I,v))end |
7 | | -function P()F:seek(S,0)local mz=F:read(2)F:seek(S,0x3C)if mz=="MZ"then return R(4)end error("!MZ")end |
| 3 | +I,X,V,H="<I4",0x80000000,809222400,[[This script will edit timestamps in a PE EXE with the Windows 95 release date. |
| 4 | +Doing so allows repeatable builds to be verified by checksum. Make a backup of your EXE before using this tool on it.]] |
| 5 | +function C(x)return F:seek("cur",x)end |
| 6 | +function S(x)return F:seek("set",x)end |
| 7 | +function R(l)local b=F:read(l)if b and#b>=l then return string.unpack(l==2 and"<I2"or I,b)end error("!EOF")end |
| 8 | +function W(p,v)S(p)F:write(string.pack(I,v))end |
| 9 | +function P()S(0)local mz=F:read(2)S(60)if mz=="MZ"then return R(4)end error("!MZ")end |
8 | 10 | function O() |
9 | | - F:seek(S,J)local s,n,h,m=F:read(4)if s~="PE\0\0"then error("!PE")end F:seek(C,2)n=R(2)F:seek(C,12)s=R(2)F:seek(C,2)h,m=F:seek(),R(2) |
10 | | - if m~=0x10b then error("!10")end F:seek(S,h+s) |
11 | | - for _=1,n do local u,o=F:seek(),F:read(8):gsub("\0.*","")F:seek(C,4)J=R(4)F:seek(C,4)K=R(4)F:seek(S,u+40)if o==".rsrc"then return end end error("!rsrc")end |
| 11 | + S(J)local s,n,h,m=F:read(4)if s~="PE\0\0"then error("!PE")end C(2)n=R(2)C(12)s=R(2)C(2)h,m=C(),R(2) |
| 12 | + if m~=267 then error("!10")end S(h+s) |
| 13 | + for _=1,n do local u,o=C(),F:read(8):gsub("\0.*","")C(4)J=R(4)C(4)K=R(4)S(u+40)if o==".rsrc"then return end end error("!rsrc")end |
12 | 14 | function B(p,s) |
13 | | - F:seek(S,(p-J)+K)local d,t,k=F:read(s),("VS_VERSION_INFO"):gsub(".","\0%1").."\0\0"k=d:find(t,1,true) |
14 | | - if k then k=k+#t+((4-((k+#t)%4))%4)+44 d,t=F:seek()+(k-s)W(d,0)W(d+4,V)end |
| 15 | + S((p-J)+K)local d,t,k=F:read(s),("VS_VERSION_INFO"):gsub(".","\0%1").."\0\0"k=d:find(t,1,true) |
| 16 | + if k then k=k+#t+((4-((k+#t)%4))%4)+44 d,t=C()+(k-s)W(d,0)W(d+4,V)end |
15 | 17 | end |
16 | 18 | function A(o,l,v) |
17 | | - local d,n,i,t,e=K+o+4 W(d,V)F:seek(C,4)n,i=R(2),R(2)t,e=n+i,d+12 |
18 | | - for j=0,t-1 do F:seek(S,e+(j*8))i,d=R(4),R(4) |
19 | | - if(d&0x80000000)~=0 then A(d&0x7FFFFFFF,l+1,v or(l==1 and i==16)) |
20 | | - elseif v and l==3 then local r=F:seek()F:seek(S,K+d)B(R(4),R(4))F:seek(S,r)end end end |
21 | | -if #arg<1 then os.exit(1)end |
| 19 | + local d,n,i,t,e=K+o+4 W(d,V)C(4)n,i=R(2),R(2)t,e=n+i,d+12 |
| 20 | + for j=0,t-1 do S(e+(j*8))i,d=R(4),R(4) |
| 21 | + if(d&X)~=0 then A(d&(X-1),l+1,v or(l==1 and i==16)) |
| 22 | + elseif v and l==3 then local r=C()S(K+d)B(R(4),R(4))S(r)end end end |
| 23 | +if #arg<1 then print(H)os.exit(1)end |
22 | 24 | F=assert(io.open(arg[1],"r+b"))J=P()W(J+8,V)O() |
23 | 25 | A(0,1)F:close() |
24 | | -print("DONE") |
| 26 | +print("OK") |
0 commit comments