diff --git a/.ccls b/.ccls
index 5ceab2d..195d346 100644
--- a/.ccls
+++ b/.ccls
@@ -4,6 +4,7 @@ gcc
 -I/usr/local/pspdev/psp/include
 -I/usr/local/pspdev/psp/sdk/include
 -I.
+-I./librsync/src
 -std=c99
 -Os
 -G0
diff --git a/.gitignore b/.gitignore
index aa2f14c..33f84fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ PARAM.SFO
 *.elf
 *.prx
 *.a
+librsync
diff --git a/Makefile b/Makefile
index 62f8c4b..836fb82 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,12 @@
+
+LIBRSYNC := librsync
+CMAKE := psp-cmake
+
 TARGET = umd_livepatch
 C_OBJS = io_funcs.o main.o
 OBJS = $(C_OBJS) imports.o
 all: $(TARGET).prx
-INCDIR = $(ARKROOT)/common/include $(ARKROOT)/core/systemctrl/include
+INCDIR = $(ARKROOT)/common/include $(ARKROOT)/core/systemctrl/include $(LIBRSYNC)/src
 CFLAGS = -std=c99 -Os -G0 -Wall
 
 ifdef DEBUG
@@ -10,7 +14,7 @@ CFLAGS += -DDEBUG=$(DEBUG)
 endif
 
 LDFLAGS =  -nostartfiles -L .
-LIBS = -lpspsystemctrl_kernel
+LIBS = -lpspsystemctrl_kernel -lrsync
 
 PSP_FW_VERSION = 660
 
@@ -27,6 +31,15 @@ libpspsystemctrl_kernel.a:
 	$(MAKE) -C $(ARKROOT)/libs/SystemCtrlForKernel
 	cp $(ARKROOT)/libs/SystemCtrlForKernel/libpspsystemctrl_kernel.a .
 
+librsync:
+	git clone https://github.com/librsync/librsync
+
+librsync.a: $(LIBRSYNC)
+	mkdir rsync_build
+	cd rsync_build; $(CMAKE) $(shell realpath $(LIBRSYNC)); make
+	mv rsync_build/librsync.a .
+	rm -rf rsync_build
+
 $(TARGET).prx:: libpspsystemctrl_kernel.a
 
 include $(PSPSDK)/lib/build.mak
diff --git a/io_funcs.c b/io_funcs.c
index bb04678..94202cc 100644
--- a/io_funcs.c
+++ b/io_funcs.c
@@ -28,7 +28,7 @@ _impl_lp_lbaToAddr(struct LbaParams *param)
 }
 
 static inline int
-_impl_lp_readDiscHeader(PspIoDrvFileArg *arg, const char *devname, void *outdata)
+_impl_lp_readDiscHeader(PspIoDrvFileArg *arg, const char *devname)
 {
     int ret;
 
@@ -44,7 +44,7 @@ _impl_lp_readDiscHeader(PspIoDrvFileArg *arg, const char *devname, void *outdata
     };
 
     ret = reserveUmdFuncs.IoDevctl(arg, devname, lp_UmdIoctl_READ_SECTORS,
-                                   &param, sizeof param, outdata, ISO_SECTOR_SIZE);
+                                   &param, sizeof param, &hdr, ISO_SECTOR_SIZE);
     return ret;
 }
 
@@ -60,7 +60,7 @@ _impl_lp_devctlRead(PspIoDrvFileArg *arg, const char *devname,
     if (first_read) {
         ret = reserveUmdFuncs.IoDevctl(arg, devname, cmd, param, inlen, outdata, outlen);
 
-        _impl_lp_readDiscHeader(arg, devname, &hdr);
+        _impl_lp_readDiscHeader(arg, devname);
         strncpy(umd_id, hdr + 0x373, 10);
         umd_id[10] = 0;
         Kprintf("Disc ID obtained: '%s'\n", umd_id);
diff --git a/rpatch.c b/rpatch.c
new file mode 100644
index 0000000..7d21dbd
--- /dev/null
+++ b/rpatch.c
@@ -0,0 +1,16 @@
+#include "io_funcs.h"
+#include "rpatch.h"
+
+#include <prototab.h>
+
+int
+lp_PatchSet_open(const char *path)
+{
+
+}
+
+int
+lp_PatchSet_covered(lp_PatchSet *ps, u32 offset)
+{
+
+}
diff --git a/rpatch.h b/rpatch.h
new file mode 100644
index 0000000..e724731
--- /dev/null
+++ b/rpatch.h
@@ -0,0 +1,20 @@
+#ifndef __RPATCH_H
+#define __RPATCH_H
+
+
+typedef struct {
+    long sector_start;
+    long sector_count;
+
+    /* If zero, block is unchanged */
+    long patch_start;
+
+    /* If smaller than sector_count, repeating data */
+    long patch_len;
+} lp_Patch;
+
+typedef struct {
+
+} lp_PatchSet;
+
+#endif //__RPATCH_H