Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

analytic sql question

715939Aug 6 2009 — edited Aug 11 2009
Dear All,
I have the following problem of getting the output table from the input table below.
Do you have any idea of doing this with the help of analytic sql?
p.s. I have done this by using pure plsql block which is too slow to run with high amount of data. Below data is just a sample, in real I have millions rows of data.

Input table:
TIME USER VALUE

1 A X
2 A X
3 B Y
4 B Y
5 A X
5 B X
6 A Y
7 B Y
7 A Y



Output table:
START_TIME END_TIME USER VALUE
1 2 A X
5 5 A X
6 7 A Y
3 4 B Y
5 5 B X
7 7 B Y
This post has been answered by Aketi Jyuuzou on Aug 6 2009
Jump to Answer

Comments

1040788

Hello there,

this tutorial was exactly what I needed, so thank you.

Your problem seems to be in this line:

int writeMemory = writeMemory(writeprocess, address, new short[0x22222222]); 

The problem is, you're creating a new short array with the length of 0x22222222. Which not only results in an java.lang.OutOfMemoryError: Java heap space

but also, if it would work, would create an empty array with the length of 0x22222222.

I think you want to write 0x22222222 as value in your address.

Correctly stored the code you'd need to write would be:

short[] sarray = new short[]{(short) 0x22222222};

But because the value is too long for the short, the value stored in your array would be the number 8738.

I think, what you want to do is to store the number 572662306, which would be the hex value, stored in an int variable.

So first of all you need to strip down your hex-value to shorts:

Short in Java uses 16 Bit = 2 Byte. 0x22222222 -> 0x2222 for your high byte and 0x2222 for your low byte

So your array would be

short[] sarray = new short[]{0x2222,0x2222};//notice, that sarray[0] is the lowbyte and sarray[1] the high byte, if you want to store 20 it would be new short[]{20,0} or if you use hex new short[]{0x14,0x00}

The next part is your writeToMemory Method. If I'm right, the method in the tutorial is a little bit wrong. The right version should be this:

public static int writeMemory(Pointer process, int address, short[] data) {

  IntByReference written = new IntByReference(0);

  int size = data.length*Short.SIZE/8;

  Memory toWrite = new Memory(size);

  for (int i = 0; i < data.length; i++) {

  toWrite.setShort(i*Short.SIZE/8,

  data[i]);

  }

  boolean b = kernel32.WriteProcessMemory(process, address, toWrite,

  size, written);

  return written.getValue();

  }

You need to calculate your offset right. And the size of your memory. Maybe you could write this method not with shorts, but with integers. But this should work.

If you pass your new array to this function, it should write 0x22222222 to your adress. If you read out your toWrite value with toWrite.getInt(0) you get the right value.

And there is one more thing. In order to write data to a process, you need to grant two access rights:

A handle to the process memory to be modified. The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process.

You have to grant the right to write data: PROCESS_VM_WRITE: 0x0020 and PROCESS_VM_OPERATION: 0x0008

So your writeProcess needs to get initialized this way:

Pointer writeprocess = openProcess(0x0020|0x0008,pid);

I hope this works for you. Let me know.

Greetings

Edit:

Because every data you write will be 1 byte to whatever count of byte I think the best way is to use the following method to write data to the memory:

public static void writeMemory(Pointer process, long address, byte[] data)

  {

  int size = data.length;

  Memory toWrite = new Memory(size);

  for(int i = 0; i < size; i++)

  {

  toWrite.setByte(i, data[i]);

  }

  boolean b = kernel32.WriteProcessMemory(process, address, toWrite, size, null);

  }

You can see some changes. First I changed all address values from int to long, because some addresses are out of range. And with all, i mean all. Not only in writeMemory, but also in readMemory and in your kernel32 Class.

Second I don't use the IntByReference anymore..

To use this method you need to store your data the following way if you would write 4 Byte data:

byte[] values = new byte[]{0x14,0x00,0x00,0x00};

This value would be the number 20. Index 0 will be the lowest byte and index 3 will be the highest byte.

And one more thing I wrote is an method which you can use to calculate your address if you have a baseAddress.

If you restart your program/game your old addresses won't point at the same values of your game. With some research (I use CheatEngine) you can get the baseaddress. This one will alway be the same.

To get from your baseaddress to the dynamic adress you use offsets.

public static long findDynAddy(Pointer process, int[] offsets, long baseAddress)

  {

  long pointer = baseAddress;

  int size = 4;

  Memory pTemp = new Memory(size);

  long pointerAddress = 0;

  for(int i = 0; i < offsets.length; i++)

  {

  if(i == 0)

  {

  kernel32.ReadProcessMemory(process, pointer, pTemp, size, null);

  }

  pointerAddress = ((pTemp.getInt(0)+offsets[i]));

  if(i != offsets.length-1)

  kernel32.ReadProcessMemory(process, pointerAddress, pTemp, size, null);

  }

  return pointerAddress;

  }

This methods gets a process, an array of offsets (hex-values) and your baseadress and returns the dynamic address.

For Solitaire the following code would give you the address to the score:

long baseAddr = 0x10002AFA8L;

  int[] offsets = new int[]{0x50,0x14};

  long addr = findDynAddy(process, offsets, baseAddr);

If somebody wants to get the whole code (user32, kernel32 and the cheater) just pm me and I will give you a link.

1 - 1
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Sep 8 2009
Added on Aug 6 2009
27 comments
15,338 views