2 #include "fileimage-patch.hpp"
3 #include "serialization.hpp"
14 uint8_t readbyte(const char* buf
, uint64_t& pos
, uint64_t size
)
17 (stringfmt() << "Attempted to read byte past the end of patch (" << pos
<< " >= "
18 << size
<< ").").throwex();
19 return static_cast<uint8_t>(buf
[pos
++]);
22 struct ips_patcher
: public patcher
24 ~ips_patcher() throw();
25 bool identify(const std::vector
<char>& patch
) throw();
26 void dopatch(std::vector
<char>& out
, const std::vector
<char>& original
,
27 const std::vector
<char>& patch
, int32_t offset
) throw(std::bad_alloc
, std::runtime_error
);
30 ips_patcher::~ips_patcher() throw()
34 bool ips_patcher::identify(const std::vector
<char>& patch
) throw()
36 return (patch
.size() > 5 && patch
[0] == 'P' && patch
[1] == 'A' && patch
[2] == 'T' &&
37 patch
[3] == 'C' && patch
[4] == 'H');
40 void ips_patcher::dopatch(std::vector
<char>& out
, const std::vector
<char>& original
,
41 const std::vector
<char>& patch
, int32_t offset
) throw(std::bad_alloc
, std::runtime_error
)
45 const char* _patch
= &patch
[0];
46 size_t psize
= patch
.size();
52 uint32_t off
= 0, l
= 0;
53 off
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 16;
54 off
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 8;
55 off
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
));
58 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 8;
59 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
));
62 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 8;
63 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
));
64 b
= readbyte(_patch
, ioffset
, psize
);
71 uint32_t noffset
= static_cast<uint32_t>(-offset
);
72 uint32_t fromoff
= min(noffset
, off
);
74 extra
= min(noffset
- fromoff
, l
);
77 if(off
+ l
>= out
.size())
81 for(uint64_t i
= 0; i
< l
; i
++)
82 out
[off
+ i
] = readbyte(_patch
, ioffset
, psize
);
84 for(uint64_t i
= 0; i
< l
; i
++)