| 1 | 2 | alfik | /*
 | 
      
         | 2 |  |  |  * Copyright (c) 2014, Aleksander Osman
 | 
      
         | 3 |  |  |  * All rights reserved.
 | 
      
         | 4 |  |  |  *
 | 
      
         | 5 |  |  |  * Redistribution and use in source and binary forms, with or without
 | 
      
         | 6 |  |  |  * modification, are permitted provided that the following conditions are met:
 | 
      
         | 7 |  |  |  *
 | 
      
         | 8 |  |  |  * * Redistributions of source code must retain the above copyright notice, this
 | 
      
         | 9 |  |  |  *   list of conditions and the following disclaimer.
 | 
      
         | 10 |  |  |  *
 | 
      
         | 11 |  |  |  * * Redistributions in binary form must reproduce the above copyright notice,
 | 
      
         | 12 |  |  |  *   this list of conditions and the following disclaimer in the documentation
 | 
      
         | 13 |  |  |  *   and/or other materials provided with the distribution.
 | 
      
         | 14 |  |  |  *
 | 
      
         | 15 |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
      
         | 16 |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
      
         | 17 |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
      
         | 18 |  |  |  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 | 
      
         | 19 |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
      
         | 20 |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
      
         | 21 |  |  |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
      
         | 22 |  |  |  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
      
         | 23 |  |  |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
      
         | 24 |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
      
         | 25 |  |  |  */
 | 
      
         | 26 |  |  |  
 | 
      
         | 27 |  |  | package ao486.test.layers;
 | 
      
         | 28 |  |  |  
 | 
      
         | 29 |  |  | import ao486.test.TestUnit;
 | 
      
         | 30 |  |  | import java.util.HashMap;
 | 
      
         | 31 |  |  | import java.util.LinkedList;
 | 
      
         | 32 |  |  | import java.util.Random;
 | 
      
         | 33 |  |  |  
 | 
      
         | 34 |  |  | public class EffectiveAddressLayerFactory {
 | 
      
         | 35 |  |  |  
 | 
      
         | 36 |  |  |     public static enum modregrm_reg_t {
 | 
      
         | 37 |  |  |         SET,
 | 
      
         | 38 |  |  |         RANDOM
 | 
      
         | 39 |  |  |     }
 | 
      
         | 40 |  |  |  
 | 
      
         | 41 |  |  |     private static long update_target(long target, long val) {
 | 
      
         | 42 |  |  |         target -= val;
 | 
      
         | 43 |  |  |         target &= 0xFFFFFFFFL;
 | 
      
         | 44 |  |  |         return target;
 | 
      
         | 45 |  |  |     }
 | 
      
         | 46 |  |  |  
 | 
      
         | 47 |  |  |     public static byte[] prepare(long value_from_mod_rm,
 | 
      
         | 48 |  |  |                                 int value_from_reg, modregrm_reg_t reg_type,
 | 
      
         | 49 |  |  |                                 int length,
 | 
      
         | 50 |  |  |                                 boolean a32,
 | 
      
         | 51 |  |  |                                 LinkedList<Layer> layers,
 | 
      
         | 52 |  |  |                                 final Random random,
 | 
      
         | 53 |  |  |                                 TestUnit test,
 | 
      
         | 54 |  |  |                                 boolean only_mem, boolean only_reg) throws Exception
 | 
      
         | 55 |  |  |     {
 | 
      
         | 56 |  |  |         int mod     = (only_reg)? 3 : random.nextInt(only_mem? 3 : 4);
 | 
      
         | 57 |  |  |         int rm      = random.nextInt(8);
 | 
      
         | 58 |  |  |  
 | 
      
         | 59 |  |  |         int scale   = random.nextInt(4);
 | 
      
         | 60 |  |  |         int index   = random.nextInt(8);
 | 
      
         | 61 |  |  |         int base    = random.nextInt(8);
 | 
      
         | 62 |  |  |  
 | 
      
         | 63 |  |  | System.out.printf("mod: %x\n", mod);
 | 
      
         | 64 |  |  | System.out.printf("rm:  %x\n", rm);
 | 
      
         | 65 |  |  |  
 | 
      
         | 66 |  |  |     boolean from_ss =
 | 
      
         | 67 |  |  |             (a32 && (mod == 1 || mod == 2) && rm == 5) ||
 | 
      
         | 68 |  |  |             (a32 && mod != 3 && rm == 4 && base == 4)  ||
 | 
      
         | 69 |  |  |             (a32 && (mod == 1 || mod == 2) && rm == 4 && base == 5) ||
 | 
      
         | 70 |  |  |             (!a32 && mod == 0 && (rm == 2 || rm == 3)) ||
 | 
      
         | 71 |  |  |             (!a32 && (mod == 1 || mod == 2) && (rm == 2 || rm == 3 || rm == 6));
 | 
      
         | 72 |  |  |  
 | 
      
         | 73 |  |  |         String segment = from_ss? "ss" : "ds";
 | 
      
         | 74 |  |  |  
 | 
      
         | 75 |  |  |         int     length_allowed  = length;
 | 
      
         | 76 |  |  |         boolean is_sib          = false;
 | 
      
         | 77 |  |  |         boolean is_memory       = true;
 | 
      
         | 78 |  |  |  
 | 
      
         | 79 |  |  |         int     disp_length = 0;
 | 
      
         | 80 |  |  |         long    disp = 0;
 | 
      
         | 81 |  |  |  
 | 
      
         | 82 |  |  |         long seg_base = 0;
 | 
      
         | 83 |  |  |         long target   = 0;
 | 
      
         | 84 |  |  |         long target_final = 0;
 | 
      
         | 85 |  |  |  
 | 
      
         | 86 |  |  |         final HashMap<String, Long> map = new HashMap<>();
 | 
      
         | 87 |  |  |         while(true) {
 | 
      
         | 88 |  |  |  
 | 
      
         | 89 |  |  |             if(mod == 3) {
 | 
      
         | 90 |  |  |                 is_memory = false;
 | 
      
         | 91 |  |  |  
 | 
      
         | 92 |  |  |                 if(length == 4) {
 | 
      
         | 93 |  |  |                     if(rm == 0) map.put("eax", value_from_mod_rm);
 | 
      
         | 94 |  |  |                     if(rm == 1) map.put("ecx", value_from_mod_rm);
 | 
      
         | 95 |  |  |                     if(rm == 2) map.put("edx", value_from_mod_rm);
 | 
      
         | 96 |  |  |                     if(rm == 3) map.put("ebx", value_from_mod_rm);
 | 
      
         | 97 |  |  |                     if(rm == 4) map.put("esp", value_from_mod_rm);
 | 
      
         | 98 |  |  |                     if(rm == 5) map.put("ebp", value_from_mod_rm);
 | 
      
         | 99 |  |  |                     if(rm == 6) map.put("esi", value_from_mod_rm);
 | 
      
         | 100 |  |  |                     if(rm == 7) map.put("edi", value_from_mod_rm);
 | 
      
         | 101 |  |  |                 }
 | 
      
         | 102 |  |  |                 else if(length == 2) {
 | 
      
         | 103 |  |  |                     if(rm == 0) map.put("ax", value_from_mod_rm & 0xFFFF);
 | 
      
         | 104 |  |  |                     if(rm == 1) map.put("cx", value_from_mod_rm & 0xFFFF);
 | 
      
         | 105 |  |  |                     if(rm == 2) map.put("dx", value_from_mod_rm & 0xFFFF);
 | 
      
         | 106 |  |  |                     if(rm == 3) map.put("bx", value_from_mod_rm & 0xFFFF);
 | 
      
         | 107 |  |  |                     if(rm == 4) map.put("sp", value_from_mod_rm & 0xFFFF);
 | 
      
         | 108 |  |  |                     if(rm == 5) map.put("bp", value_from_mod_rm & 0xFFFF);
 | 
      
         | 109 |  |  |                     if(rm == 6) map.put("si", value_from_mod_rm & 0xFFFF);
 | 
      
         | 110 |  |  |                     if(rm == 7) map.put("di", value_from_mod_rm & 0xFFFF);
 | 
      
         | 111 |  |  |                 }
 | 
      
         | 112 |  |  |                 else if(length == 1) {
 | 
      
         | 113 |  |  |                     if(rm == 0) map.put("al", value_from_mod_rm & 0xFF);
 | 
      
         | 114 |  |  |                     if(rm == 1) map.put("cl", value_from_mod_rm & 0xFF);
 | 
      
         | 115 |  |  |                     if(rm == 2) map.put("dl", value_from_mod_rm & 0xFF);
 | 
      
         | 116 |  |  |                     if(rm == 3) map.put("bl", value_from_mod_rm & 0xFF);
 | 
      
         | 117 |  |  |                     if(rm == 4) map.put("ah", value_from_mod_rm & 0xFF);
 | 
      
         | 118 |  |  |                     if(rm == 5) map.put("ch", value_from_mod_rm & 0xFF);
 | 
      
         | 119 |  |  |                     if(rm == 6) map.put("dh", value_from_mod_rm & 0xFF);
 | 
      
         | 120 |  |  |                     if(rm == 7) map.put("bh", value_from_mod_rm & 0xFF);
 | 
      
         | 121 |  |  |                 }
 | 
      
         | 122 |  |  |                 break;
 | 
      
         | 123 |  |  |             }
 | 
      
         | 124 |  |  | System.out.println("segment: " + segment);
 | 
      
         | 125 |  |  |             long seg_limit = Layer.norm(test.getInput(segment + "_limit"));
 | 
      
         | 126 |  |  |             seg_base  = Layer.norm(test.getInput(segment + "_base"));
 | 
      
         | 127 |  |  |             if(seg_limit < length) length_allowed = (int)(length - seg_limit);
 | 
      
         | 128 |  |  |             target =
 | 
      
         | 129 |  |  |                     (seg_limit == 0)?       0 :
 | 
      
         | 130 |  |  |                     (seg_limit < length)?   random.nextInt((int)seg_limit) :
 | 
      
         | 131 |  |  |                                             random.nextInt((int)(seg_limit - length +1));
 | 
      
         | 132 |  |  |  
 | 
      
         | 133 |  |  |             if(!a32) {
 | 
      
         | 134 |  |  |                 target &= 0xFFFF;
 | 
      
         | 135 |  |  |             }
 | 
      
         | 136 |  |  |             target_final = target;
 | 
      
         | 137 |  |  |  
 | 
      
         | 138 |  |  | System.out.printf("target: %x, length: %d, final loc: %08x\n", target_final, length, seg_base + target);
 | 
      
         | 139 |  |  |             boolean target_ok = true;
 | 
      
         | 140 |  |  |             for(int i=0; i<length; i++) {
 | 
      
         | 141 |  |  |                 if(test.is_memory_not_random((int)(seg_base + target + i))) target_ok = false;
 | 
      
         | 142 |  |  |             }
 | 
      
         | 143 |  |  |             if(target_ok == false) continue;
 | 
      
         | 144 |  |  |  
 | 
      
         | 145 |  |  |             if(!a32) {
 | 
      
         | 146 |  |  |                 if(mod == 1) {
 | 
      
         | 147 |  |  |                     long disp8 = random.nextInt(256);
 | 
      
         | 148 |  |  |                     map.put("disp8", disp8);
 | 
      
         | 149 |  |  |                     if((disp8 >> 7) == 1) disp8 |= 0xFF00;
 | 
      
         | 150 |  |  |                     target = update_target(target, disp8);
 | 
      
         | 151 |  |  |                 }
 | 
      
         | 152 |  |  |                 if(mod == 2) {
 | 
      
         | 153 |  |  |                     long disp16 = random.nextInt(65536);
 | 
      
         | 154 |  |  |                     map.put("disp16", disp16);
 | 
      
         | 155 |  |  |                     target = update_target(target, disp16);
 | 
      
         | 156 |  |  |                 }
 | 
      
         | 157 |  |  |  
 | 
      
         | 158 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 0) {
 | 
      
         | 159 |  |  |                     long si = Layer.norm(random.nextInt(65536));
 | 
      
         | 160 |  |  |                     map.put("si", si);
 | 
      
         | 161 |  |  |                     target = update_target(target, si);
 | 
      
         | 162 |  |  |                     map.put("bx", target);
 | 
      
         | 163 |  |  |                 }
 | 
      
         | 164 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 1) {
 | 
      
         | 165 |  |  |                     long di = Layer.norm(random.nextInt(65536));
 | 
      
         | 166 |  |  |                     map.put("di", di);
 | 
      
         | 167 |  |  |                     target = update_target(target, di);
 | 
      
         | 168 |  |  |                     map.put("bx", target);
 | 
      
         | 169 |  |  |                 }
 | 
      
         | 170 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 2) {
 | 
      
         | 171 |  |  |                     long si = Layer.norm(random.nextInt(65536));
 | 
      
         | 172 |  |  |                     map.put("si", si);
 | 
      
         | 173 |  |  |                     target = update_target(target, si);
 | 
      
         | 174 |  |  |                     map.put("bp", target);
 | 
      
         | 175 |  |  |                 }
 | 
      
         | 176 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 3) {
 | 
      
         | 177 |  |  |                     long di = Layer.norm(random.nextInt(65536));
 | 
      
         | 178 |  |  |                     map.put("di", di);
 | 
      
         | 179 |  |  |                     target = update_target(target, di);
 | 
      
         | 180 |  |  |                     map.put("bp", target);
 | 
      
         | 181 |  |  |                 }
 | 
      
         | 182 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 4) {
 | 
      
         | 183 |  |  |                     map.put("si", target);
 | 
      
         | 184 |  |  |                 }
 | 
      
         | 185 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 5) {
 | 
      
         | 186 |  |  |                     map.put("di", target);
 | 
      
         | 187 |  |  |                 }
 | 
      
         | 188 |  |  |                 if(mod == 0 && rm == 6) {
 | 
      
         | 189 |  |  |                     map.put("disp16", target);
 | 
      
         | 190 |  |  |                 }
 | 
      
         | 191 |  |  |                 if((mod == 1 || mod == 2) && rm == 6) {
 | 
      
         | 192 |  |  |                     map.put("bp", target);
 | 
      
         | 193 |  |  |                 }
 | 
      
         | 194 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 7) {
 | 
      
         | 195 |  |  |                     map.put("bx", target);
 | 
      
         | 196 |  |  |                 }
 | 
      
         | 197 |  |  |             }
 | 
      
         | 198 |  |  |  
 | 
      
         | 199 |  |  |             if(a32) {
 | 
      
         | 200 |  |  |                 if(mod == 1 && rm != 4) {
 | 
      
         | 201 |  |  |                     long disp8 = random.nextInt(256);
 | 
      
         | 202 |  |  |                     map.put("disp8", disp8);
 | 
      
         | 203 |  |  |                     if((disp8 >> 7) == 1) disp8 |= 0xFFFFFF00;
 | 
      
         | 204 |  |  |                     target = update_target(target, disp8);
 | 
      
         | 205 |  |  | System.out.printf("disp8: %x\n", disp8);
 | 
      
         | 206 |  |  |                 }
 | 
      
         | 207 |  |  |                 if(mod == 2 && rm != 4) {
 | 
      
         | 208 |  |  |                     long disp32 = Layer.norm(random.nextInt());
 | 
      
         | 209 |  |  |                     map.put("disp32", disp32);
 | 
      
         | 210 |  |  |                     target = update_target(target, disp32);
 | 
      
         | 211 |  |  |                 }
 | 
      
         | 212 |  |  |  
 | 
      
         | 213 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 0) {
 | 
      
         | 214 |  |  |                     map.put("eax", target);
 | 
      
         | 215 |  |  |                 }
 | 
      
         | 216 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 1) {
 | 
      
         | 217 |  |  |                     map.put("ecx", target);
 | 
      
         | 218 |  |  |                 }
 | 
      
         | 219 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 2) {
 | 
      
         | 220 |  |  |                     map.put("edx", target);
 | 
      
         | 221 |  |  |                 }
 | 
      
         | 222 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 3) {
 | 
      
         | 223 |  |  |                     map.put("ebx", target);
 | 
      
         | 224 |  |  |                 }
 | 
      
         | 225 |  |  |                 if(mod == 0 && rm == 5) {
 | 
      
         | 226 |  |  |                     map.put("disp32", target);
 | 
      
         | 227 |  |  |                 }
 | 
      
         | 228 |  |  |                 if((mod == 1 || mod == 2) && rm == 5) {
 | 
      
         | 229 |  |  |                     map.put("ebp", target);
 | 
      
         | 230 |  |  |                 }
 | 
      
         | 231 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 6) {
 | 
      
         | 232 |  |  |                     map.put("esi", target);
 | 
      
         | 233 |  |  |                 }
 | 
      
         | 234 |  |  |                 if((mod == 0 || mod == 1 || mod == 2) && rm == 7) {
 | 
      
         | 235 |  |  |                     map.put("edi", target);
 | 
      
         | 236 |  |  |                 }
 | 
      
         | 237 |  |  |  
 | 
      
         | 238 |  |  |                 if(rm == 4) {
 | 
      
         | 239 |  |  |                     is_sib = true;
 | 
      
         | 240 |  |  |  
 | 
      
         | 241 |  |  |                     HashMap<String, Integer> sib_map = new HashMap<>();
 | 
      
         | 242 |  |  |  
 | 
      
         | 243 |  |  |                     sib_map.put("eax", 0);
 | 
      
         | 244 |  |  |                     sib_map.put("ecx", 0);
 | 
      
         | 245 |  |  |                     sib_map.put("edx", 0);
 | 
      
         | 246 |  |  |                     sib_map.put("ebx", 0);
 | 
      
         | 247 |  |  |                     sib_map.put("esp", 0);
 | 
      
         | 248 |  |  |                     sib_map.put("ebp", 0);
 | 
      
         | 249 |  |  |                     sib_map.put("esi", 0);
 | 
      
         | 250 |  |  |                     sib_map.put("edi", 0);
 | 
      
         | 251 |  |  |  
 | 
      
         | 252 |  |  |                     if(base == 0) sib_map.put("eax", sib_map.get("eax") + 1);
 | 
      
         | 253 |  |  |                     if(base == 1) sib_map.put("ecx", sib_map.get("ecx") + 1);
 | 
      
         | 254 |  |  |                     if(base == 2) sib_map.put("edx", sib_map.get("edx") + 1);
 | 
      
         | 255 |  |  |                     if(base == 3) sib_map.put("ebx", sib_map.get("ebx") + 1);
 | 
      
         | 256 |  |  |                     if(base == 4) sib_map.put("esp", sib_map.get("esp") + 1);
 | 
      
         | 257 |  |  |                     if(base == 5 && (mod == 1 || mod == 2)) sib_map.put("ebp", sib_map.get("ebp") + 1);
 | 
      
         | 258 |  |  |                     if(base == 6) sib_map.put("esi", sib_map.get("esi") + 1);
 | 
      
         | 259 |  |  |                     if(base == 7) sib_map.put("edi", sib_map.get("edi") + 1);
 | 
      
         | 260 |  |  |  
 | 
      
         | 261 |  |  |                     if(mod == 0 && base == 5)   sib_map.put("disp32", 1);
 | 
      
         | 262 |  |  |                     if(mod == 1)                sib_map.put("disp8",  1);
 | 
      
         | 263 |  |  |                     if(mod == 2)                sib_map.put("disp32", 1);
 | 
      
         | 264 |  |  |  
 | 
      
         | 265 |  |  |                     int count = (scale == 0)? 1 :
 | 
      
         | 266 |  |  |                                 (scale == 1)? 2 :
 | 
      
         | 267 |  |  |                                 (scale == 2)? 4 :
 | 
      
         | 268 |  |  |                                               8;
 | 
      
         | 269 |  |  |                     if(index == 0) sib_map.put("eax", sib_map.get("eax") + count);
 | 
      
         | 270 |  |  |                     if(index == 1) sib_map.put("ecx", sib_map.get("ecx") + count);
 | 
      
         | 271 |  |  |                     if(index == 2) sib_map.put("edx", sib_map.get("edx") + count);
 | 
      
         | 272 |  |  |                     if(index == 3) sib_map.put("ebx", sib_map.get("ebx") + count);
 | 
      
         | 273 |  |  |                     if(index == 5) sib_map.put("ebp", sib_map.get("ebp") + count);
 | 
      
         | 274 |  |  |                     if(index == 6) sib_map.put("esi", sib_map.get("esi") + count);
 | 
      
         | 275 |  |  |                     if(index == 7) sib_map.put("edi", sib_map.get("edi") + count);
 | 
      
         | 276 |  |  |  
 | 
      
         | 277 |  |  |                     //-----
 | 
      
         | 278 |  |  |  
 | 
      
         | 279 |  |  |                     if(sib_map.containsKey("disp8")) {
 | 
      
         | 280 |  |  |                         long disp8 = random.nextInt(256);
 | 
      
         | 281 |  |  |                         map.put("disp8", disp8);
 | 
      
         | 282 |  |  |                         if((disp8 >> 7) == 1) disp8 |= 0xFFFFFF00;
 | 
      
         | 283 |  |  |                         target = update_target(target, disp8);
 | 
      
         | 284 |  |  |  
 | 
      
         | 285 |  |  |                         sib_map.remove("disp8");
 | 
      
         | 286 |  |  |                     }
 | 
      
         | 287 |  |  |  
 | 
      
         | 288 |  |  |                     String found = null;
 | 
      
         | 289 |  |  |                     for(String s : sib_map.keySet()) {
 | 
      
         | 290 |  |  |                         if(sib_map.get(s) == 1) {
 | 
      
         | 291 |  |  |                             found = s;
 | 
      
         | 292 |  |  |                             break;
 | 
      
         | 293 |  |  |                         }
 | 
      
         | 294 |  |  |                     }
 | 
      
         | 295 |  |  |  
 | 
      
         | 296 |  |  |                     while(found != null) {
 | 
      
         | 297 |  |  |                         String key = sib_map.keySet().toArray(new String[0])[random.nextInt(sib_map.keySet().size())];
 | 
      
         | 298 |  |  |                         if(sib_map.get(key) != 1) continue;
 | 
      
         | 299 |  |  |                         found = key;
 | 
      
         | 300 |  |  |                         sib_map.remove(found);
 | 
      
         | 301 |  |  |                         break;
 | 
      
         | 302 |  |  |                     }
 | 
      
         | 303 |  |  |  
 | 
      
         | 304 |  |  |                     if(found != null) {
 | 
      
         | 305 |  |  |                         for(String s : sib_map.keySet()) {
 | 
      
         | 306 |  |  |                             int coeff = sib_map.get(s);
 | 
      
         | 307 |  |  |  
 | 
      
         | 308 |  |  |                             if(coeff > 0) {
 | 
      
         | 309 |  |  |                                 long val32 = Layer.norm(random.nextInt());
 | 
      
         | 310 |  |  |                                 while((val32 % coeff) != 0) val32--;
 | 
      
         | 311 |  |  |                                 map.put(s, val32/coeff);
 | 
      
         | 312 |  |  |                                 target = update_target(target, val32);
 | 
      
         | 313 |  |  |                             }
 | 
      
         | 314 |  |  |                         }
 | 
      
         | 315 |  |  |                         map.put(found, target);
 | 
      
         | 316 |  |  |                     }
 | 
      
         | 317 |  |  |                     else {
 | 
      
         | 318 |  |  |                         while(true) {
 | 
      
         | 319 |  |  |                             boolean removed = false;
 | 
      
         | 320 |  |  |                             for(String s : sib_map.keySet()) {
 | 
      
         | 321 |  |  |                                 if(sib_map.get(s) == 0) {
 | 
      
         | 322 |  |  |                                     sib_map.remove(s);
 | 
      
         | 323 |  |  |                                     removed = true;
 | 
      
         | 324 |  |  |                                     break;
 | 
      
         | 325 |  |  |                                 }
 | 
      
         | 326 |  |  |                             }
 | 
      
         | 327 |  |  |                             if(removed == false) break;
 | 
      
         | 328 |  |  |                         }
 | 
      
         | 329 |  |  |  
 | 
      
         | 330 |  |  |                         if(sib_map.size() != 1) throw new Exception("Internal test error");
 | 
      
         | 331 |  |  |  
 | 
      
         | 332 |  |  |                         int coeff = 0;
 | 
      
         | 333 |  |  |                         String key = null;
 | 
      
         | 334 |  |  |                         for(String s : sib_map.keySet()) {
 | 
      
         | 335 |  |  |                             coeff = sib_map.get(s);
 | 
      
         | 336 |  |  |                             key = s;
 | 
      
         | 337 |  |  |                             break;
 | 
      
         | 338 |  |  |                         }
 | 
      
         | 339 |  |  |  
 | 
      
         | 340 |  |  |                         if((target % coeff) != 0) continue;
 | 
      
         | 341 |  |  |  
 | 
      
         | 342 |  |  |                         map.put(key, target/coeff);
 | 
      
         | 343 |  |  |                     }
 | 
      
         | 344 |  |  |                 }
 | 
      
         | 345 |  |  |             }
 | 
      
         | 346 |  |  |             break;
 | 
      
         | 347 |  |  |         }
 | 
      
         | 348 |  |  |         if(map.containsKey("eax")) layers.addFirst(new Layer(random) { long eax() { return map.get("eax").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 349 |  |  |         if(map.containsKey("ecx")) layers.addFirst(new Layer(random) { long ecx() { return map.get("ecx").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 350 |  |  |         if(map.containsKey("edx")) layers.addFirst(new Layer(random) { long edx() { return map.get("edx").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 351 |  |  |         if(map.containsKey("ebx")) layers.addFirst(new Layer(random) { long ebx() { return map.get("ebx").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 352 |  |  |         if(map.containsKey("esp")) layers.addFirst(new Layer(random) { long esp() { return map.get("esp").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 353 |  |  |         if(map.containsKey("ebp")) layers.addFirst(new Layer(random) { long ebp() { return map.get("ebp").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 354 |  |  |         if(map.containsKey("esi")) layers.addFirst(new Layer(random) { long esi() { return map.get("esi").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 355 |  |  |         if(map.containsKey("edi")) layers.addFirst(new Layer(random) { long edi() { return map.get("edi").longValue() & 0xFFFFFFFFL; } });
 | 
      
         | 356 |  |  |  
 | 
      
         | 357 |  |  |         if(map.containsKey("ax")) layers.addFirst(new Layer(random) { long eax() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("ax").intValue()) & 0xFFFF); } });
 | 
      
         | 358 |  |  |         if(map.containsKey("cx")) layers.addFirst(new Layer(random) { long ecx() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("cx").intValue()) & 0xFFFF); } });
 | 
      
         | 359 |  |  |         if(map.containsKey("dx")) layers.addFirst(new Layer(random) { long edx() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("dx").intValue()) & 0xFFFF); } });
 | 
      
         | 360 |  |  |         if(map.containsKey("bx")) layers.addFirst(new Layer(random) { long ebx() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("bx").intValue()) & 0xFFFF); } });
 | 
      
         | 361 |  |  |         if(map.containsKey("sp")) layers.addFirst(new Layer(random) { long esp() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("sp").intValue()) & 0xFFFF); } });
 | 
      
         | 362 |  |  |         if(map.containsKey("bp")) layers.addFirst(new Layer(random) { long ebp() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("bp").intValue()) & 0xFFFF); } });
 | 
      
         | 363 |  |  |         if(map.containsKey("si")) layers.addFirst(new Layer(random) { long esi() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("si").intValue()) & 0xFFFF); } });
 | 
      
         | 364 |  |  |         if(map.containsKey("di")) layers.addFirst(new Layer(random) { long edi() { return (random.nextInt(65536) << 16) | ((int)Layer.norm(map.get("di").intValue()) & 0xFFFF); } });
 | 
      
         | 365 |  |  |  
 | 
      
         | 366 |  |  |         if(map.containsKey("al")) layers.addFirst(new Layer(random) { long eax() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("al").intValue()) & 0xFF); } });
 | 
      
         | 367 |  |  |         if(map.containsKey("ah")) layers.addFirst(new Layer(random) { long eax() { return random.nextInt(256) | (((int)Layer.norm(map.get("ah").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
 | 
      
         | 368 |  |  |         if(map.containsKey("bl")) layers.addFirst(new Layer(random) { long ebx() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("bl").intValue()) & 0xFF); } });
 | 
      
         | 369 |  |  |         if(map.containsKey("bh")) layers.addFirst(new Layer(random) { long ebx() { return random.nextInt(256) | (((int)Layer.norm(map.get("bh").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
 | 
      
         | 370 |  |  |         if(map.containsKey("cl")) layers.addFirst(new Layer(random) { long ecx() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("cl").intValue()) & 0xFF); } });
 | 
      
         | 371 |  |  |         if(map.containsKey("ch")) layers.addFirst(new Layer(random) { long ecx() { return random.nextInt(256) | (((int)Layer.norm(map.get("ch").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
 | 
      
         | 372 |  |  |         if(map.containsKey("dl")) layers.addFirst(new Layer(random) { long edx() { return (random.nextInt(16777216) << 8) | ((int)Layer.norm(map.get("dl").intValue()) & 0xFF); } });
 | 
      
         | 373 |  |  |         if(map.containsKey("dh")) layers.addFirst(new Layer(random) { long edx() { return random.nextInt(256) | (((int)Layer.norm(map.get("dh").intValue()) & 0xFF) << 8) | (random.nextInt(65536) << 16); } });
 | 
      
         | 374 |  |  |  
 | 
      
         | 375 |  |  |         if(is_memory) {
 | 
      
         | 376 |  |  | System.out.printf("value_from_mod_rm: %x\n", value_from_mod_rm);
 | 
      
         | 377 |  |  |             target_map.clear();
 | 
      
         | 378 |  |  |             for(int i=0; i<length_allowed; i++) {
 | 
      
         | 379 |  |  |                 target_map.put(seg_base+target_final+i, (byte)((value_from_mod_rm >> (i*8)) & 0xFF));
 | 
      
         | 380 |  |  |             }
 | 
      
         | 381 |  |  |             layers.addFirst(new Layer(random) {
 | 
      
         | 382 |  |  |                 public boolean is_memory_not_random(long address) { return target_map.containsKey(address); }
 | 
      
         | 383 |  |  |  
 | 
      
         | 384 |  |  |                 public Byte get_memory(long address) {
 | 
      
         | 385 |  |  |                     return (target_map.containsKey(address) == false)? null : target_map.get(address);
 | 
      
         | 386 |  |  |                 }
 | 
      
         | 387 |  |  |             });
 | 
      
         | 388 |  |  |         }
 | 
      
         | 389 |  |  |  
 | 
      
         | 390 |  |  |  
 | 
      
         | 391 |  |  |         // prepare modregrm bytes
 | 
      
         | 392 |  |  |         if(map.containsKey("disp8")) {
 | 
      
         | 393 |  |  |             if(disp_length != 0) throw new Exception("Internal test error");
 | 
      
         | 394 |  |  |             disp = map.get("disp8");
 | 
      
         | 395 |  |  |             disp_length = 1;
 | 
      
         | 396 |  |  |         }
 | 
      
         | 397 |  |  |         if(map.containsKey("disp16")) {
 | 
      
         | 398 |  |  |             if(disp_length != 0) throw new Exception("Internal test error");
 | 
      
         | 399 |  |  |             disp = map.get("disp16");
 | 
      
         | 400 |  |  |             disp_length = 2;
 | 
      
         | 401 |  |  |         }
 | 
      
         | 402 |  |  |         if(map.containsKey("disp32")) {
 | 
      
         | 403 |  |  |             if(disp_length != 0) throw new Exception("Internal test error");
 | 
      
         | 404 |  |  |             disp = map.get("disp32");
 | 
      
         | 405 |  |  |             disp_length = 4;
 | 
      
         | 406 |  |  |         }
 | 
      
         | 407 |  |  |  
 | 
      
         | 408 |  |  |         int reg = (reg_type == modregrm_reg_t.SET)? value_from_reg : random.nextInt(8);
 | 
      
         | 409 |  |  |  
 | 
      
         | 410 |  |  |         LinkedList<Byte> modregrm_bytes = new LinkedList<>();
 | 
      
         | 411 |  |  |  
 | 
      
         | 412 |  |  |         modregrm_bytes.add((byte)( ((mod & 0x3) << 6) | ((reg & 0x7) << 3) | ((rm & 0x7) << 0) ));
 | 
      
         | 413 |  |  |  
 | 
      
         | 414 |  |  | System.out.printf("modregrm: %x\n", modregrm_bytes.get(0));
 | 
      
         | 415 |  |  | System.out.printf("len: %d - %d\n", length_allowed, length);
 | 
      
         | 416 |  |  | System.out.printf("seg_base: %x\n", seg_base);
 | 
      
         | 417 |  |  |  
 | 
      
         | 418 |  |  |         if(is_sib)              modregrm_bytes.add((byte)( ((scale & 0x3) << 6) | ((index & 0x7) << 3) | ((base & 0x7) << 0) ));
 | 
      
         | 419 |  |  |         if(disp_length == 1)    modregrm_bytes.add((byte)(disp & 0xFF));
 | 
      
         | 420 |  |  |         if(disp_length == 2) {
 | 
      
         | 421 |  |  |             modregrm_bytes.add((byte)(disp & 0xFF));
 | 
      
         | 422 |  |  |             modregrm_bytes.add((byte)((disp >> 8) & 0xFF));
 | 
      
         | 423 |  |  |         }
 | 
      
         | 424 |  |  |         if(disp_length == 4) {
 | 
      
         | 425 |  |  |             modregrm_bytes.add((byte)(disp & 0xFF));
 | 
      
         | 426 |  |  |             modregrm_bytes.add((byte)((disp >> 8) & 0xFF));
 | 
      
         | 427 |  |  |             modregrm_bytes.add((byte)((disp >> 16) & 0xFF));
 | 
      
         | 428 |  |  |             modregrm_bytes.add((byte)((disp >> 24) & 0xFF));
 | 
      
         | 429 |  |  |         }
 | 
      
         | 430 |  |  |  
 | 
      
         | 431 |  |  |         byte bytes[] = new byte[modregrm_bytes.size()];
 | 
      
         | 432 |  |  |         for(int i=0; i<bytes.length; i++) bytes[i] = modregrm_bytes.get(i);
 | 
      
         | 433 |  |  |  
 | 
      
         | 434 |  |  |         return bytes;
 | 
      
         | 435 |  |  |     }
 | 
      
         | 436 |  |  |     static HashMap<Long, Byte> target_map = new HashMap<>();
 | 
      
         | 437 |  |  | }
 |