| 396 | |
| 397 | |
| 398 | byte* Unpack::ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt) |
| 399 | { |
| 400 | byte *SrcData=Data; |
| 401 | switch(Flt->Type) |
| 402 | { |
| 403 | case FILTER_E8: |
| 404 | case FILTER_E8E9: |
| 405 | { |
| 406 | uint FileOffset=(uint)WrittenFileSize; |
| 407 | |
| 408 | const uint FileSize=0x1000000; |
| 409 | byte CmpByte2=Flt->Type==FILTER_E8E9 ? 0xe9:0xe8; |
| 410 | // DataSize is unsigned, so we use "CurPos+4" and not "DataSize-4" |
| 411 | // to avoid overflow for DataSize<4. |
| 412 | for (uint CurPos=0;CurPos+4<DataSize;) |
| 413 | { |
| 414 | byte CurByte=*(Data++); |
| 415 | CurPos++; |
| 416 | if (CurByte==0xe8 || CurByte==CmpByte2) |
| 417 | { |
| 418 | uint Offset=(CurPos+FileOffset)%FileSize; |
| 419 | uint Addr=RawGet4(Data); |
| 420 | |
| 421 | // We check 0x80000000 bit instead of '< 0' comparison |
| 422 | // not assuming int32 presence or uint size and endianness. |
| 423 | if ((Addr & 0x80000000)!=0) // Addr<0 |
| 424 | { |
| 425 | if (((Addr+Offset) & 0x80000000)==0) // Addr+Offset>=0 |
| 426 | RawPut4(Addr+FileSize,Data); |
| 427 | } |
| 428 | else |
| 429 | if (((Addr-FileSize) & 0x80000000)!=0) // Addr<FileSize |
| 430 | RawPut4(Addr-Offset,Data); |
| 431 | |
| 432 | Data+=4; |
| 433 | CurPos+=4; |
| 434 | } |
| 435 | } |
| 436 | } |
| 437 | return SrcData; |
| 438 | case FILTER_ARM: |
| 439 | // 2019-11-15: we turned off ARM filter by default when compressing, |
| 440 | // mostly because it is inefficient for modern 64 bit ARM binaries. |
| 441 | // It was turned on by default in 5.0 - 5.80b3 , so we still need it |
| 442 | // here for compatibility with some of previously created archives. |
| 443 | { |
| 444 | uint FileOffset=(uint)WrittenFileSize; |
| 445 | // DataSize is unsigned, so we use "CurPos+3" and not "DataSize-3" |
| 446 | // to avoid overflow for DataSize<3. |
| 447 | for (uint CurPos=0;CurPos+3<DataSize;CurPos+=4) |
| 448 | { |
| 449 | byte *D=Data+CurPos; |
| 450 | if (D[3]==0xeb) // BL command with '1110' (Always) condition. |
| 451 | { |
| 452 | uint Offset=D[0]+uint(D[1])*0x100+uint(D[2])*0x10000; |
| 453 | Offset-=(FileOffset+CurPos)/4; |
| 454 | D[0]=(byte)Offset; |
| 455 | D[1]=(byte)(Offset>>8); |