/*## (c) SECURITY EXPLORATIONS    2018 poland                                #*/
/*##     http://www.security-explorations.com                                #*/

/* THIS SOFTWARE IS PROTECTED BY DOMESTIC AND INTERNATIONAL COPYRIGHT LAWS    */
/* UNAUTHORISED COPYING OF THIS SOFTWARE IN EITHER SOURCE OR BINARY FORM IS   */
/* EXPRESSLY FORBIDDEN. ANY USE, INCLUDING THE REPRODUCTION, MODIFICATION,    */
/* DISTRIBUTION, TRANSMISSION, RE-PUBLICATION, STORAGE OR DISPLAY OF ANY      */
/* PART OF THE SOFTWARE, FOR COMMERCIAL OR ANY OTHER PURPOSES REQUIRES A      */
/* VALID LICENSE FROM THE COPYRIGHT HOLDER.                                   */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    */
/* SECURITY EXPLORATIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF  */
/* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                                  */

import java.lang.*;
import java.util.*;
import com.adb.xion.util.*;

public class Utils {

 private static Random random;

 static {
  random=new Random();
  long seed=System.currentTimeMillis();
  random.setSeed(seed);
 }

 public static int java2cstring(String s) {
  if (s==null) return 0;

  NativeCode nc=NativeCode.getInstance();

  byte chars[]=s.getBytes();
  int ptr=nc.malloc(chars.length+1);
  
  for(int i=0;i<chars.length;i++) {
   int b=(chars[i])&0xff;
   Memory.write_byte(ptr+i,b);
  }

  Memory.write_byte(ptr+chars.length,0);

  return ptr;
 }

 public static String c2javastring(int addr) {
  if (addr==0) return null;

  int size=0;
  int i=0;

  while(Memory.read_byte(addr+i)!=0) {
   i++;
   size++;
  }

  byte chars[]=new byte[size];

  for(i=0;i<size;i++) {
   chars[i]=(byte)Memory.read_byte(addr+i);
  }
  
  return new String(chars);
 }

 public static String buf2javastring(int addr,int size) {
  if (addr==0) return null;

  int i=0;

  byte chars[]=new byte[size];

  for(i=0;i<size;i++) {
   chars[i]=(byte)Memory.read_byte(addr+i);
  }
  
  return new String(chars);
 }

 public static byte[] buf2barray(int addr,int size) {
  if (addr==0) return null;

  byte bytes[]=new byte[size];

  for(int i=0;i<size;i++) {
   bytes[i]=(byte)Memory.read_byte(addr+i);
  }
  
  return bytes;
 }

 public static int[] buf2iarray(int addr,int size) {
  if (addr==0) return null;

  int ints[]=new int[size];

  for(int i=0;i<size;i++) {
   ints[i]=Memory.read_byte(addr+i);
  }
  
  return ints;
 }

 public static int barray2buf(byte[] barray) {
  if (barray==null) return 0;

  NativeCode nc=NativeCode.getInstance();

  int ptr=nc.malloc(barray.length);
  
  for(int i=0;i<barray.length;i++) {
   int b=(barray[i])&0xff;
   Memory.write_byte(ptr+i,b);
  }

  return ptr;
 }

 public static int iarray2buf(int[] iarray) {
  if (iarray==null) return 0;

  NativeCode nc=NativeCode.getInstance();

  int ptr=nc.malloc(iarray.length);
  
  for(int i=0;i<iarray.length;i++) {
   int b=iarray[i]&0xff;
   Memory.write_byte(ptr+i,b);
  }

  return ptr;
 }

 public static int code2buf(int[] iarray) {
  if (iarray==null) return 0;

  NativeCode nc=NativeCode.getInstance();

  int ptr=nc.malloc(iarray.length*4);
  
  for(int i=0;i<iarray.length;i++) {
   int b=iarray[i];
   Memory.write_dword(ptr+4*i,b);
  }

  int res=Syscall.mprotect(ptr&0xfffff000,ELFUtils.PAGESIZE,Syscall.PROT_ALL);

  Utils.sleep(1000); 

  return ptr;
 }

 public static void memset(int addr,int val,int size) {
  while(((addr&0x03)!=0)&&(size>0)) {
   Memory.write_byte(addr,val);
   addr++;
   size--;
  }

  if (size>0) {
   val&=0xff;
   int word=(val<<24)|(val<<16)|(val<<8)|val;
   int cnt=size>>2;

   for(int i=0;i<cnt;i++) {
    Memory.write_dword(addr,word);
    addr+=4;
    size-=4;
   }

   while(size>0) {
    Memory.write_byte(addr,val);
    addr++;
    size--;
   }
  }
 }

 public static void memcpy(byte[] from,int addr,int size) {
  for(int i=0;i<size;i++) {
   int val=((int)from[i])&0xff;
   Memory.write_byte(addr+i,val);
  }
 }

 public static void memcpy(int from,int to,int size) {
  for(int i=0;i<size;i++) {
   int val=Memory.read_byte(from+i);
   Memory.write_byte(to+i,val);
  }
 }

 public static int parse_hex(String s) {
  int val=0;

  for(int i=0;i<s.length();i++) {
   char ch=s.charAt(i);
   int d;

   if ((ch>='0')&&(ch<='9')) {
    d=ch-'0';
   } else

   if ((ch>='a')&&(ch<='f')) {
    d=10+ch-'a';
   } else

   if ((ch>='A')&&(ch<='F')) {
    d=10+ch-'A';
   } else return -1;

   val=(val<<4)|(d&0x0f);
  }

  return val;
 }

 public static String hex_value(int val,int max) {
  String s="";
  for(int i=0;i<max;i++) {
   s+="0";
  }

  s+=Integer.toHexString(val);

  return s.substring(s.length()-max);
 }

 public static String padded_int(int val,int max) {
  String s="";
  for(int i=0;i<max;i++) {
   s+="0";
  }

  s+=val;

  return s.substring(s.length()-max);
 }

 public static String padded_string(String s,int space) {
  int cnt=s.length();

  String pad="";

  if (cnt<space) {
   pad=s;

   for(int i=0;i<(space-cnt);i++) {
    pad+=" ";
   }
  } else pad=s.substring(s.length()-space);

  return pad;
 }

 public static String padded_string_left(String s,int space) {
  int cnt=s.length();

  String pad="";

  if (cnt<space) {
   for(int i=0;i<(space-cnt);i++) {
    pad+=" ";
   }

   pad+=s;
  } else pad=s.substring(s.length()-space);

  return pad;
 }

 public static void sleep(int num) {
  try {
   Thread.sleep(num);
  } catch(Throwable t) {}
 }

 public static int random() {
  return random.nextInt();
 }

 public static String random_string() {
  int r=random();
  return hex_value(r,8);
 }

 public static byte[] base64_decode(String s) {
  return Base64.decodeFast(s);
 }

}
