Closed 6ag closed 2 years ago
There was a bug in the api that prevented the memory search from working properly. I am using python-3.6.8 frida-15.1.14.
Do you have ceversion set properly in config.json? I would appreciate it if you could let me know what kind of problem you are experiencing.
Mobile device: iPhone X OS version: 14.0 Frida version: 15.1.12 Python version: 3.8.2
When I click Frist Scan in Cheat Engine 7.3, the app will crash after a while and the following error will appear:
Traceback (most recent call last):
File "/Users/feng/DevEnv/frida-ceserver-main/ceserver.py", line 476, in main_thread
ret = handler(conn, command, thread_count)
File "/Users/feng/DevEnv/frida-ceserver-main/ceserver.py", line 296, in handler
ret = API.ReadProcessMemory(address, size)
File "/Users/feng/.pyenv/versions/3.8.2/lib/python3.8/site-packages/frida/core.py", line 468, in method
return script._rpc_request('call', js_name, args, **kwargs)
File "/Users/feng/.pyenv/versions/3.8.2/lib/python3.8/site-packages/frida/core.py", line 26, in wrapper
return f(*args, **kwargs)
File "/Users/feng/.pyenv/versions/3.8.2/lib/python3.8/site-packages/frida/core.py", line 400, in _rpc_request
raise result[2]
frida.InvalidOperationError: script has been destroyed
config.json:
{
"target": "",
"targetOS": 2,
"mode": 0,
"arch": 2,
"fix_module_size": false,
"ceversion": "7.3",
"manualParser": false,
"javaDissect": false
}
I reinstalled python-3.6.8 frida-15.1.14 and still got the same error:
Traceback (most recent call last):
File "/Users/feng/DevEnv/frida-ceserver-main/ceserver.py", line 476, in main_thread
ret = handler(conn, command, thread_count)
File "/Users/feng/DevEnv/frida-ceserver-main/ceserver.py", line 296, in handler
ret = API.ReadProcessMemory(address, size)
File "/Users/feng/.pyenv/versions/3.6.8/lib/python3.6/site-packages/frida/core.py", line 468, in method
return script._rpc_request('call', js_name, args, **kwargs)
File "/Users/feng/.pyenv/versions/3.6.8/lib/python3.6/site-packages/frida/core.py", line 26, in wrapper
return f(*args, **kwargs)
File "/Users/feng/.pyenv/versions/3.6.8/lib/python3.6/site-packages/frida/core.py", line 400, in _rpc_request
raise result[2]
frida.InvalidOperationError: script has been destroyed
When I use the memory search function, the APP will crash after searching for about 1 minute.
Is the frida-server on your iPhone device and the frida on your PC both up-to-date? Did it work with the previous version I distributed? I'm sorry for all the questions.
The previous version worked fine for me, and at the time I remember there was no config.json file.
I now iPhone frida-server and PC frida are the latest version, Python also reinstalled 3.6.
I just found an older version that I downloaded from GitHub last July and found that it still works fine. I am using python-3.8.2 frida-15.1.14.
Thank you very much for your report. I will compare with the past ver and try to find the cause.
Unfortunately, I tested and found that older versions still occasionally flicker when searching memory.
I sincerely hope to fix this issue, thank you.
Sorry to interrupt again, but after testing I have made a new discovery. When Frida launches the APP using spawn mode, the APP has run successfully, but the script has some errors:
Traceback (most recent call last):
File "/Users/feng/DevEnv/frida-ceserver-main/main.py", line 107, in <module>
main(target)
File "/Users/feng/DevEnv/frida-ceserver-main/main.py", line 50, in main
process_id = device.spawn([app_identifier])
File "/Users/feng/.pyenv/versions/3.8.2/lib/python3.8/site-packages/frida/core.py", line 26, in wrapper
return f(*args, **kwargs)
File "/Users/feng/.pyenv/versions/3.8.2/lib/python3.8/site-packages/frida/core.py", line 149, in spawn
return self._impl.spawn(program, argv, envp, env, cwd, stdio, aux_options)
frida.TimedOutError: unexpectedly timed out while waiting for app to launch
When launched using attach mode, everything seems to work fine. The memory search also works fine and there is no app flashing.
However, when I do a pointer scan, an error message appears: Failure copying target process memory
.
What should I do to use the pointer scan function properly?
I found the reason for the app flashing. When searching memory or scanning the pointer, the memory occupied by the app keeps increasing, and it flashes when it exceeds the memory limit.
EXC_RESOURCE -> Bird[14899] exceeded mem limit: ActiveHard 1850 MB (fatal)
However, I don't know how to avoid the continuous growth of memory usage, which I guess is caused by Frida. Brother, can you solve this problem?
Executing Memory.readByteArray() function in a large amount will cause the memory occupied by the target APP to keep increasing and will not be released automatically, which will eventually lead to the target APP being killed by the system.
Thank you for all the information. If possible, I will try to implement memory loading on my own in iOS.
Thank you brother, I hope this tool will become more and more perfect.
readprocessmemory: function (address, size) {
try {
if (ptr(address).isNull() == false) {
var ret = Memory.readByteArray(ptr(address), size);
return false;
} else {
return false;
}
} catch (e) {
return false;
}
},
What happens to the memory usage if I only read the memory and do not return? This may be a rpc problem.
I tested again and again for a day and found that it was indeed the call to the Memory.readByteArray function that caused the memory leak. If you don't execute Memory.readByteArray and return ByteArray directly, APP memory is not increased.
My guess is that there is a memory leak inside the Memory.readByteArray function.
Within the handler function CECMD.CMD_READPROCESSMEMORY branch of ceserver.py, I tried not executing the ReadProcessMemory function and there is no change in APP memory usage.
elif (command == CECMD.CMD_READPROCESSMEMORY):
handle = reader.ReadUInt32()
address = reader.ReadUInt64()
size = reader.ReadUInt32()
compress = reader.ReadInt8()
# ret = API.ReadProcessMemory(address, size)
# if (compress == 0):
# if ret != False:
# writer.WriteInt32(len(ret))
# ns.sendall(ret)
# else:
# writer.WriteInt32(0)
# else:
# if ret != False:
# compress_data = zlib.compress(ret, level=compress)
# writer.WriteInt32(len(ret))
# writer.WriteInt32(len(compress_data))
# ns.sendall(compress_data)
# else:
# writer.WriteInt32(0)
# writer.WriteInt32(0)
writer.WriteInt32(0)
And by executing the ReadProcessMemory function, the memory will skyrocket.
elif (command == CECMD.CMD_READPROCESSMEMORY):
handle = reader.ReadUInt32()
address = reader.ReadUInt64()
size = reader.ReadUInt32()
compress = reader.ReadInt8()
ret = API.ReadProcessMemory(address, size)
# if (compress == 0):
# if ret != False:
# writer.WriteInt32(len(ret))
# ns.sendall(ret)
# else:
# writer.WriteInt32(0)
# else:
# if ret != False:
# compress_data = zlib.compress(ret, level=compress)
# writer.WriteInt32(len(ret))
# writer.WriteInt32(len(compress_data))
# ns.sendall(compress_data)
# else:
# writer.WriteInt32(0)
# writer.WriteInt32(0)
writer.WriteInt32(0)
Get the memory occupied by.
+ (double)usedMemory
{
task_basic_info_data_t taskInfo;
mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
kern_return_t kernReturn = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&taskInfo, &infoCount);
if (kernReturn != KERN_SUCCESS) {
return NSNotFound;
}
return taskInfo.resident_size / 1024.0 / 1024.0;
}
Get the remaining free memory of the app.
+ (double)availableMemory
{
if (@available(iOS 13.0, *)) {
return os_proc_available_memory() / 1024.0 / 1024.0;
}
vm_statistics_data_t vmStats;
mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
if (kernReturn != KERN_SUCCESS) {
return NSNotFound;
}
return (vm_page_size *vmStats.free_count) / 1024.0 / 1024.0;
}
Before I started testing, usedMemory
was getting a memory footprint of about 600M and availableMemory
was getting about 1000M of free memory.
Cheat Engine starts scanning memory, specifying the search range 0x105000000 - 0x110000000
. The memory footprint obtained by usedMemory
continues to increase to 1300M, and the available memory obtained by availableMemory
slowly decreases to 800M.
Then test the scan pointer and set the base address range to 0x105000000 - 0x110000000
. The memory usage obtained by usedMemory
continues to increase to about 1500M, and then slowly decreases to about 700M. The available memory fetched by availableMemory
slowly decreases to 200M.
At this time I have to scan the memory again, or scan the pointer, and the app will definitely be killed by the system.
Thank you for the information. If the solution seems to be too difficult, I would consider using the native ceserver only for the memory loading process.
Cheat Engine <-> python <-> native ceserver(ios)
Thank you brother. Looking forward to your update.
I implemented the above type of memory reading from the outside. https://www.youtube.com/watch?v=KkKDSTcecwg
Thank you very much, I have tested it and it's perfect. The performance is great 👍🏻.
If possible, it would be helpful if you could make sure it is fixed in the latest commit.
Doesn't work on my device, the Python version I'm using is 3.8.2 and the Frida version is 14.2.14.
Can you tell me which version of Python and Frida you are using?
Thank you, brother.