| 120 | |
| 121 | |
| 122 | bool RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType) |
| 123 | { |
| 124 | switch(FilterType) |
| 125 | { |
| 126 | case VMSF_E8: |
| 127 | case VMSF_E8E9: |
| 128 | { |
| 129 | byte *Data=Mem; |
| 130 | uint DataSize=R[4],FileOffset=R[6]; |
| 131 | |
| 132 | if (DataSize>VM_MEMSIZE || DataSize<4) |
| 133 | return false; |
| 134 | |
| 135 | const uint FileSize=0x1000000; |
| 136 | byte CmpByte2=FilterType==VMSF_E8E9 ? 0xe9:0xe8; |
| 137 | for (uint CurPos=0;CurPos<DataSize-4;) |
| 138 | { |
| 139 | byte CurByte=*(Data++); |
| 140 | CurPos++; |
| 141 | if (CurByte==0xe8 || CurByte==CmpByte2) |
| 142 | { |
| 143 | uint Offset=CurPos+FileOffset; |
| 144 | uint Addr=RawGet4(Data); |
| 145 | |
| 146 | // We check 0x80000000 bit instead of '< 0' comparison |
| 147 | // not assuming int32 presence or uint size and endianness. |
| 148 | if ((Addr & 0x80000000)!=0) // Addr<0 |
| 149 | { |
| 150 | if (((Addr+Offset) & 0x80000000)==0) // Addr+Offset>=0 |
| 151 | RawPut4(Addr+FileSize,Data); |
| 152 | } |
| 153 | else |
| 154 | if (((Addr-FileSize) & 0x80000000)!=0) // Addr<FileSize |
| 155 | RawPut4(Addr-Offset,Data); |
| 156 | Data+=4; |
| 157 | CurPos+=4; |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | break; |
| 162 | case VMSF_ITANIUM: |
| 163 | { |
| 164 | byte *Data=Mem; |
| 165 | uint DataSize=R[4],FileOffset=R[6]; |
| 166 | |
| 167 | if (DataSize>VM_MEMSIZE || DataSize<21) |
| 168 | return false; |
| 169 | |
| 170 | uint CurPos=0; |
| 171 | |
| 172 | FileOffset>>=4; |
| 173 | |
| 174 | while (CurPos<DataSize-21) |
| 175 | { |
| 176 | int Byte=(Data[0]&0x1f)-0x10; |
| 177 | if (Byte>=0) |
| 178 | { |
| 179 | static byte Masks[16]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0}; |