flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
typedef 19 Jun 2013, 13:24
So here's a tutorial of how to write native libraries for JAVA classes in Assembly using of course FASM.
I have a 64 bit OS so on 32-bit it should be straightforward. I have included the JNI functions struct as well. jni.inc Code: ; ; Include file put together by typedef (board.flatassembler.net) ; struct JNIEnv reserved0 dq ? reserved1 dq ? reserved2 dq ? reserved3 dq ? GetVersion dq ? DefineClass dq ? FindClass dq ? FromReflectedMethod dq ? FromReflectedField dq ? ToReflectedMethod dq ? GetSuperclass dq ? IsAssignableFrom dq ? ToReflectedField dq ? Throw dq ? ThrowNew dq ? ExceptionOccurred dq ? ExceptionDescribe dq ? ExceptionClear dq ? FatalError dq ? PushLocalFrame dq ? PopLocalFrame dq ? NewGlobalRef dq ? DeleteGlobalRef dq ? DeleteLocalRef dq ? IsSameObject dq ? NewLocalRef dq ? EnsureLocalCapacity dq ? AllocObject dq ? NewObject dq ? NewObjectV dq ? NewObjectA dq ? GetObjectClass dq ? IsInstanceOf dq ? GetMethodID dq ? CallObjectMethod dq ? CallObjectMethodV dq ? CallObjectMethodA dq ? CallBooleanMethod dq ? CallBooleanMethodV dq ? CallBooleanMethodA dq ? CallByteMethod dq ? CallByteMethodV dq ? CallByteMethodA dq ? CallCharMethod dq ? CallCharMethodV dq ? CallCharMethodA dq ? CallShortMethod dq ? CallShortMethodV dq ? CallShortMethodA dq ? CallIntMethod dq ? CallIntMethodV dq ? CallIntMethodA dq ? CallLongMethod dq ? CallLongMethodV dq ? CallLongMethodA dq ? CallFloatMethod dq ? CallFloatMethodV dq ? CallFloatMethodA dq ? CallDoubleMethod dq ? CallDoubleMethodV dq ? CallDoubleMethodA dq ? CallVoidMethod dq ? CallVoidMethodV dq ? CallVoidMethodA dq ? CallNonvirtualObjectMethod dq ? CallNonvirtualObjectMethodV dq ? CallNonvirtualObjectMethodA dq ? CallNonvirtualBooleanMethod dq ? CallNonvirtualBooleanMethodV dq ? CallNonvirtualBooleanMethodA dq ? CallNonvirtualByteMethod dq ? CallNonvirtualByteMethodV dq ? CallNonvirtualByteMethodA dq ? CallNonvirtualCharMethod dq ? CallNonvirtualCharMethodV dq ? CallNonvirtualCharMethodA dq ? CallNonvirtualShortMethod dq ? CallNonvirtualShortMethodV dq ? CallNonvirtualShortMethodA dq ? CallNonvirtualIntMethod dq ? CallNonvirtualIntMethodV dq ? CallNonvirtualIntMethodA dq ? CallNonvirtualLongMethod dq ? CallNonvirtualLongMethodV dq ? CallNonvirtualLongMethodA dq ? CallNonvirtualFloatMethod dq ? CallNonvirtualFloatMethodV dq ? CallNonvirtualFloatMethodA dq ? CallNonvirtualDoubleMethod dq ? CallNonvirtualDoubleMethodV dq ? CallNonvirtualDoubleMethodA dq ? CallNonvirtualVoidMethod dq ? CallNonvirtualVoidMethodV dq ? CallNonvirtualVoidMethodA dq ? GetFieldID dq ? GetObjectField dq ? GetBooleanField dq ? GetByteField dq ? GetCharField dq ? GetShortField dq ? GetIntField dq ? GetLongField dq ? GetFloatField dq ? GetDoubleField dq ? SetObjectField dq ? SetBooleanField dq ? SetByteField dq ? SetCharField dq ? SetShortField dq ? SetIntField dq ? SetLongField dq ? SetFloatField dq ? SetDoubleField dq ? GetStaticMethodID dq ? CallStaticObjectMethod dq ? CallStaticObjectMethodV dq ? CallStaticObjectMethodA dq ? CallStaticBooleanMethod dq ? CallStaticBooleanMethodV dq ? CallStaticBooleanMethodA dq ? CallStaticByteMethod dq ? CallStaticByteMethodV dq ? CallStaticByteMethodA dq ? CallStaticCharMethod dq ? CallStaticCharMethodV dq ? CallStaticCharMethodA dq ? CallStaticShortMethod dq ? CallStaticShortMethodV dq ? CallStaticShortMethodA dq ? CallStaticIntMethod dq ? CallStaticIntMethodV dq ? CallStaticIntMethodA dq ? CallStaticLongMethod dq ? CallStaticLongMethodV dq ? CallStaticLongMethodA dq ? CallStaticFloatMethod dq ? CallStaticFloatMethodV dq ? CallStaticFloatMethodA dq ? CallStaticDoubleMethod dq ? CallStaticDoubleMethodV dq ? CallStaticDoubleMethodA dq ? CallStaticVoidMethod dq ? CallStaticVoidMethodV dq ? CallStaticVoidMethodA dq ? GetStaticFieldID dq ? GetStaticObjectField dq ? GetStaticBooleanField dq ? GetStaticByteField dq ? GetStaticCharField dq ? GetStaticShortField dq ? GetStaticIntField dq ? GetStaticLongField dq ? GetStaticFloatField dq ? GetStaticDoubleField dq ? SetStaticObjectField dq ? SetStaticBooleanField dq ? SetStaticByteField dq ? SetStaticCharField dq ? SetStaticShortField dq ? SetStaticIntField dq ? SetStaticLongField dq ? SetStaticFloatField dq ? SetStaticDoubleField dq ? NewString dq ? GetStringLength dq ? GetStringChars dq ? ReleaseStringChars dq ? NewStringUTF dq ? GetStringUTFLength dq ? GetStringUTFChars dq ? ReleaseStringUTFChars dq ? GetArrayLength dq ? NewObjectArray dq ? GetObjectArrayElement dq ? SetObjectArrayElement dq ? NewBooleanArray dq ? NewByteArray dq ? NewCharArray dq ? NewShortArray dq ? NewIntArray dq ? NewLongArray dq ? NewFloatArray dq ? NewDoubleArray dq ? GetBooleanArrayElements dq ? GetByteArrayElements dq ? GetCharArrayElements dq ? GetShortArrayElements dq ? GetIntArrayElements dq ? GetLongArrayElements dq ? GetFloatArrayElements dq ? GetDoubleArrayElements dq ? ReleaseBooleanArrayElements dq ? ReleaseByteArrayElements dq ? ReleaseCharArrayElements dq ? ReleaseShortArrayElements dq ? ReleaseIntArrayElements dq ? ReleaseLongArrayElements dq ? ReleaseFloatArrayElements dq ? ReleaseDoubleArrayElements dq ? GetBooleanArrayRegion dq ? GetByteArrayRegion dq ? GetCharArrayRegion dq ? GetShortArrayRegion dq ? GetIntArrayRegion dq ? GetLongArrayRegion dq ? GetFloatArrayRegion dq ? GetDoubleArrayRegion dq ? SetBooleanArrayRegion dq ? SetByteArrayRegion dq ? SetCharArrayRegion dq ? SetShortArrayRegion dq ? SetIntArrayRegion dq ? SetLongArrayRegion dq ? SetFloatArrayRegion dq ? SetDoubleArrayRegion dq ? RegisterNatives dq ? UnregisterNatives dq ? MonitorEnter dq ? MonitorExit dq ? GetJavaVM dq ? GetStringRegion dq ? GetStringUTFRegion dq ? GetPrimitiveArrayCritical dq ? ReleasePrimitiveArrayCritical dq ? GetStringCritical dq ? ReleaseStringCritical dq ? NewWeakGlobalRef dq ? DeleteWeakGlobalRef dq ? ExceptionCheck dq ? NewDirectByteBuffer dq ? GetDirectBufferAdqress dq ? GetDirectBufferCapacity dq ? GetObjectRefType dq ? ends <dll_name>.asm (mine is libNative) Code: format PE64 GUI 4.0 DLL at 0x10000000 ; Force base address include 'win64a.inc' include 'jni.inc' section '.data' data readable align 8 hello db 'String from java = "%s"',0Dh,0Ah,00 unicode du 'Hello World from Assembly',0Dh,0Ah,00 len = $ - unicode section '.text' code readable executable proc sayHello ; JNIEnv *env, jobject obj, jstring string push rbx push rsi push rdi ; rcx = env, rdx = obj, r8 = jstring, push rdx ; pointer to this class sub rsp,0x20 ; not used here mov rbx, [rcx] virtual at rbx env JNIEnv end virtual ; get C string from JAVA Object mov rdi, r8 ; save jstring mov rdx, r8 ; String object to get string from xor r8, r8 ; null ;mov rcx, env ; rcx is already JNIEnv call [env.GetStringUTFChars] ; RAX = const char *; mov rsi, rax ; save returned pointer to char * mov rdx, rax mov rcx, hello ; Awww My Gewdness ! No stack cleaning ? call [printf] ; free C string mov r8, rsi mov rdx, rdi mov rcx, rbx call [env.ReleaseStringUTFChars] add rsp,0x20 pop rax ; return pointer to self pop rdi pop rsi pop rbx ret endp proc getString ; JNIEnv *env, jobject obj push rbx push rsi push rdi mov rbx, [rcx] virtual at rbx jni JNIEnv end virtual ; create java.lang.String mov r8, len mov rdx, unicode call [jni.NewString] pop rdi pop rsi pop rbx ret endp section '.idata' import data readable library msvcrt,'msvcrt.dll' import msvcrt,\ printf,'printf' section '.edata' export data readable export 'libNative.DLL',\ sayHello,'Java_com_typedef_jnitest_callAssembly',\ getString,'Java_com_typedef_jnitest_getString' java source. Must be in appropriate package of course or remove the package and change the exported function names as well Code: package com.typedef; public class jnitest { /** * Returns the same object * @param string * @return jnitest */ private native jnitest callAssembly(String s); private native String getString(); static{ System.loadLibrary("libnative"); /* DLL name. Note lowercase of classname! Must be in same directory or absolute path */ } public static void main(String ... args){ System.out.println( new jnitest().callAssembly("hello world from java").getString() ); } } If you're not familiar with JNI or JAVA here's a read: http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/jniTOC.html EDIT: ??? Last edited by typedef on 25 May 2014, 20:39; edited 1 time in total |
|||
![]() |
|
TmX 20 Jun 2013, 06:31
And what changes should I make so the example can be run in 32-bit OS?
Changing rsp to esp, rdi to edi, rax to ,eax, and so on? And what about r8? |
|||
![]() |
|
TmX 21 Jun 2013, 04:10
I mean things like:
Code: mov rdi, r8 ; save jstring mov rdx, r8 ; String object to get string from xor r8, r8 ; null What's the 32-bit equivalent? And thanks for the other tips ![]() |
|||
![]() |
|
typedef 21 Jun 2013, 05:35
On 32 bit. You don't need to actually save the pointers in registers since they're already passed on through the stack.
Code: push 0 push dword[ebp+0x10] ; Our 2rd parameter on the stack, (The String object), r8 on x64 push dword[ebp+0x8] ; Our 1st parameter on the stack (The JNIEnv structure pointer) call [env.GetStringUTFChars] ; Function we are calling = const char * GetStringUTFChars(JNIEnv *env, jstring string,jboolean *isCopy); Also, I'm sure you're familiar with the C calling convention. On 32 bit you'll need to clean the stack after calling the printf function. I'll see if I can create a 32-bit VM and make a 32-bit version if you have more questions. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.