Fix IPS patching
- Fix crash on applying IPS patch - Make IPS offset rewriting work right
This commit is contained in:
parent
b8e236972a
commit
993eeb20d3
1 changed files with 23 additions and 14 deletions
|
@ -80,9 +80,9 @@ namespace
|
||||||
if(patch.size() < roffset + 3)
|
if(patch.size() < roffset + 3)
|
||||||
throw std::runtime_error("Patch incomplete");
|
throw std::runtime_error("Patch incomplete");
|
||||||
uint32_t a, b, c;
|
uint32_t a, b, c;
|
||||||
a = patch[roffset + 0];
|
a = static_cast<uint8_t>(patch[roffset + 0]);
|
||||||
b = patch[roffset + 1];
|
b = static_cast<uint8_t>(patch[roffset + 1]);
|
||||||
c = patch[roffset + 2];
|
c = static_cast<uint8_t>(patch[roffset + 2]);
|
||||||
uint32_t rec_off = a * 65536 + b * 256 + c;
|
uint32_t rec_off = a * 65536 + b * 256 + c;
|
||||||
if(rec_off == 0x454F46) {
|
if(rec_off == 0x454F46) {
|
||||||
//EOF.
|
//EOF.
|
||||||
|
@ -91,16 +91,16 @@ namespace
|
||||||
}
|
}
|
||||||
if(patch.size() < roffset + 5)
|
if(patch.size() < roffset + 5)
|
||||||
throw std::runtime_error("Patch incomplete");
|
throw std::runtime_error("Patch incomplete");
|
||||||
a = patch[roffset + 3];
|
a = static_cast<uint8_t>(patch[roffset + 3]);
|
||||||
b = patch[roffset + 4];
|
b = static_cast<uint8_t>(patch[roffset + 4]);
|
||||||
uint32_t rec_size = a * 256 + b;
|
uint32_t rec_size = a * 256 + b;
|
||||||
uint32_t rec_rlesize = 0;
|
uint32_t rec_rlesize = 0;
|
||||||
uint32_t rec_rawsize = 0;
|
uint32_t rec_rawsize = 0;
|
||||||
if(!rec_size) {
|
if(!rec_size) {
|
||||||
if(patch.size() < roffset + 8)
|
if(patch.size() < roffset + 8)
|
||||||
throw std::runtime_error("Patch incomplete");
|
throw std::runtime_error("Patch incomplete");
|
||||||
a = patch[roffset + 5];
|
a = static_cast<uint8_t>(patch[roffset + 5]);
|
||||||
b = patch[roffset + 6];
|
b = static_cast<uint8_t>(patch[roffset + 6]);
|
||||||
rec_rlesize = a * 256 + b;
|
rec_rlesize = a * 256 + b;
|
||||||
rec_rawsize = 8;
|
rec_rawsize = 8;
|
||||||
} else
|
} else
|
||||||
|
@ -110,15 +110,21 @@ namespace
|
||||||
throw std::runtime_error("Offset exceeds IPS 16MiB limit");
|
throw std::runtime_error("Offset exceeds IPS 16MiB limit");
|
||||||
if(rec_noff < 0) {
|
if(rec_noff < 0) {
|
||||||
//This operation needs to clip the start as it is out of bounds.
|
//This operation needs to clip the start as it is out of bounds.
|
||||||
while(rec_size > 0 && rec_noff + rec_size <= 0) {
|
if(rec_size) {
|
||||||
rec_noff++;
|
if(rec_size > -rec_noff) {
|
||||||
rec_size--;
|
rec_noff = 0;
|
||||||
|
rec_size -= -rec_noff;
|
||||||
|
} else
|
||||||
|
rec_size = 0;
|
||||||
}
|
}
|
||||||
while(rec_rlesize > 0 && rec_noff + rec_rlesize <= 0) {
|
if(rec_rlesize) {
|
||||||
rec_noff++;
|
if(rec_rlesize > -rec_noff) {
|
||||||
rec_rlesize--;
|
rec_noff = 0;
|
||||||
|
rec_rlesize -= -rec_noff;
|
||||||
|
} else
|
||||||
|
rec_rlesize = 0;
|
||||||
}
|
}
|
||||||
if(rec_noff + rec_size + rec_rlesize <= 0)
|
if(!rec_size && !rec_rlesize)
|
||||||
return std::make_pair(0, rec_rawsize); //Completely out of bounds.
|
return std::make_pair(0, rec_rawsize); //Completely out of bounds.
|
||||||
}
|
}
|
||||||
//Write the modified record.
|
//Write the modified record.
|
||||||
|
@ -172,6 +178,9 @@ namespace
|
||||||
std::vector<char> ret;
|
std::vector<char> ret;
|
||||||
ret.resize(p.size);
|
ret.resize(p.size);
|
||||||
memcpy(&ret[0], p.data, p.size);
|
memcpy(&ret[0], p.data, p.size);
|
||||||
|
//No, these can't be freed.
|
||||||
|
p.source(NULL, 0);
|
||||||
|
p.modify(NULL, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue