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

public class SysData {

 public static final int SD_MAGIC       = 0x53453131;

 public static final int SD_KMEMFD      = 0x00;
 public static final int SD_CUSTSYSCALL = 0x01;

 public static final int SD_MAX         = 0x02;

 private static int addr;

 static {
  if (Memory.read_dword(ELFUtils.DEFAULT_BASE)!=SD_MAGIC) {
   int size=SD_MAX*0x04;

   addr=NativeCode.getInstance().malloc(size);  
   Utils.memset(addr,-1,size);

   Syscall.mprotect(ELFUtils.DEFAULT_BASE,0x08,Syscall.PROT_READ|Syscall.PROT_WRITE);

   Memory.write_dword(ELFUtils.DEFAULT_BASE,SD_MAGIC);
   Memory.write_dword(ELFUtils.DEFAULT_BASE+0x04,addr);
  } else {
   addr=Memory.read_dword(ELFUtils.DEFAULT_BASE+0x04);
  }

 }

 public static boolean is_cached(int idx) {
  if (idx<SD_MAX) {
   if (Memory.read_dword(addr+idx*0x04)!=-1) return true;
  }

  return false;
 }

 public static int get_cached(int idx) {
  if (idx<SD_MAX) {
   return Memory.read_dword(addr+idx*0x04);
  }

  return -1;
 }

 public static void cache(int idx,int val) {
  if (idx<SD_MAX) {
   Memory.write_dword(addr+idx*0x04,val);
  }
 }

}
