# IDA Python: ida\_search.find\_text() ignores first argument? (start\_ea)

**URL:** https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97
**Category:** Support
**Created:** [January 25, 2025, 11:24pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97 "2025-01-25T23:24:21Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Harding](https://sea2.discourse-cdn.com/flex002/user_avatar/community.hex-rays.com/harding/32/37_2.png) [@Harding](https://community.hex-rays.com/u/Harding)
#### Post date: [January 25, 2025, 11:24pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/1 "2025-01-25T23:24:21Z")

</div>

According to [Official doc on find\_text](https://python.docs.hex-rays.com/namespaceida__search.html#a77a11e661d85d3613f1b5e1149ca06af)  
The first argument is start\_ea but when I try to use it, the first hit is before my start\_ea. My code looks something like this (I have simplified it slightly)

```python
import ida_search
import ida_idaapi
import ida_ida
from typing import List

def search_text(arg_search_for: str,
                arg_search_direction_down: bool = True,
                arg_search_is_regex: bool = False,
                arg_start_ea: int = 0,
                arg_max_hits: int = 1,
                arg_debug: bool = False) -> List[int]:
    res = []
    l_max_hits = arg_max_hits
    l_min_ea = arg_start_ea if arg_start_ea else ida_ida.inf_get_min_ea()

    l_search_flags = ida_search.SEARCH_DOWN if arg_search_direction_down else ida_search.SEARCH_UP
    l_search_flags |= ida_search.SEARCH_NEXT
    l_search_flags |= ida_search.SEARCH_BRK # return BADADDR if the search was cancelled
    if arg_search_is_regex:
        l_search_flags |= ida_search.SEARCH_REGEX
    l_start_next_search_at = l_min_ea
    while True:
        l_useless_y: int = 0
        l_useless_x: int = 0
        print(f"Calling ida_search.find_text(0x{l_start_next_search_at:x}, {l_useless_y}, {l_useless_x}, '{arg_search_for}', {l_search_flags})")
        l_start_next_search_at = ida_search.find_text(l_start_next_search_at, l_useless_y, l_useless_x, arg_search_for, l_search_flags)
        print(f"result from ida_search.find_text(): 0x{l_start_next_search_at:x}")
        if l_start_next_search_at == ida_idaapi.BADADDR:
            break
        res.append(l_start_next_search_at)
        l_start_next_search_at += 1
        l_max_hits -= 1
        if l_max_hits == 0:
            break
    return res

```

When I search for something that I know exists multiple times:

```python
In[42]: search_text("xor eax, eax", arg_max_hits=2)
Calling ida_search.find_text(0x180000000, 0, 0, 'xor eax, eax', 3)
result from ida_search.find_text(): 0x1800014f7
Calling ida_search.find_text(0x1800014f8, 0, 0, 'xor eax, eax', 3)
result from ida_search.find_text(): 0x1800014f7

Out[42]: [0x1800014f7 (UrlHashA + 0x37), 0x1800014f7 (UrlHashA + 0x37)]

```

---

<div class="post-metadata">

### Author: ![Milanek](https://avatars.discourse-cdn.com/v4/letter/m/d07c76/32.png) [@Milanek](https://community.hex-rays.com/u/Milanek)
#### Post date: [January 26, 2025, 11:31am UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/2 "2025-01-26T11:31:18Z")

</div>

It works as expected. You are searching towards lower address (arg\_search\_direction\_down: bool = True)

---

<div class="post-metadata">

### Author: ![Harding](https://sea2.discourse-cdn.com/flex002/user_avatar/community.hex-rays.com/harding/32/37_2.png) [@Harding](https://community.hex-rays.com/u/Harding)
#### Post date: [January 26, 2025, 4:05pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/3 "2025-01-26T16:05:54Z")

</div>

According to ida\_search.py line 77 it reads:

```Python
SEARCH_DOWN = _ida_search.SEARCH_DOWN
r"""
search towards higher addresses
"""

```

And I tried to use ida\_search.SEARCH\_UP instead and got the exact same result

---

<div class="post-metadata">

### Author: ![Harding](https://sea2.discourse-cdn.com/flex002/user_avatar/community.hex-rays.com/harding/32/37_2.png) [@Harding](https://community.hex-rays.com/u/Harding)
#### Post date: [January 26, 2025, 4:46pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/4 "2025-01-26T16:46:07Z")

</div>

After som investigation, it seems that the find\_text() starts from get\_item\_head(start\_ea) meaning I have to jump to the end if the item after each search. This code works as expected:

```python
import ida_search
import ida_idaapi
import ida_ida
import ida_bytes
from typing import List

def search_text(arg_search_for: str,
                arg_search_direction_down: bool = True,
                arg_search_is_regex: bool = False,
                arg_start_ea: int = 0,
                arg_max_hits: int = 1,
                arg_debug: bool = False) -> List[int]:
    res = []
    l_max_hits = arg_max_hits
    l_min_ea = arg_start_ea if arg_start_ea else ida_ida.inf_get_min_ea()

    l_search_flags = ida_search.SEARCH_DOWN if arg_search_direction_down else ida_search.SEARCH_UP
    l_search_flags |= ida_search.SEARCH_NEXT
    l_search_flags |= ida_search.SEARCH_BRK # return BADADDR if the search was cancelled
    if arg_search_is_regex:
        l_search_flags |= ida_search.SEARCH_REGEX
    l_start_next_search_at = l_min_ea
    while True:
        l_useless_y: int = 0
        l_useless_x: int = 0
        print(f"Calling ida_search.find_text(0x{l_start_next_search_at:x}, {l_useless_y}, {l_useless_x}, '{arg_search_for}', {l_search_flags})")
        l_start_next_search_at = ida_search.find_text(l_start_next_search_at, l_useless_y, l_useless_x, arg_search_for, l_search_flags)
        print(f"result from ida_search.find_text(): 0x{l_start_next_search_at:x}")
        if l_start_next_search_at == ida_idaapi.BADADDR:
            break
        res.append(l_start_next_search_at)
        # Here is the fix:
        l_start_next_search_at = ida_bytes.get_item_end(l_start_next_search_at) if arg_search_direction_down else (ida_bytes.get_item_head(l_start_next_search_at) - 1)
        l_max_hits -= 1
        if l_max_hits == 0:
            break
    return res

```

---

<div class="post-metadata">

### Author: ![Milanek](https://avatars.discourse-cdn.com/v4/letter/m/d07c76/32.png) [@Milanek](https://community.hex-rays.com/u/Milanek)
#### Post date: [January 26, 2025, 5:56pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/5 "2025-01-26T17:56:50Z")

</div>

Oops. My bad, I only remembered that the up/down naming is tricky.

Btw, I think that if you do `yield l_start_next_search_at` instead of `res.append(l_start_next_search_at)` you wont’t have to deal with the `l_max_hits` variable.

I should discourage you from using `find_text()`. The disassembly is not stored anywhere and has to be generated on the fly. This is slow.  
There are usually better ways how to achieve the same goal.

---

<div class="post-metadata">

### Author: ![Harding](https://sea2.discourse-cdn.com/flex002/user_avatar/community.hex-rays.com/harding/32/37_2.png) [@Harding](https://community.hex-rays.com/u/Harding)
#### Post date: [January 26, 2025, 7:37pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/6 "2025-01-26T19:37:40Z")

</div>

I agree that find\_text() should not be used very often. I’m writing a wrapper around some of the IDA Python APIs and a friend of mine wanted find\_text() so I added it.

You can check it out at [link to Github: community\_base.py](https://github.com/Harding-Stardust/community_base)

---

<div class="post-metadata">

### Author: ![Milanek](https://avatars.discourse-cdn.com/v4/letter/m/d07c76/32.png) [@Milanek](https://community.hex-rays.com/u/Milanek)
#### Post date: [January 26, 2025, 10:41pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/7 "2025-01-26T22:41:59Z")

</div>

To quote Madame de Maintenon:

> Friends don’t let friends use `find_text()`.

Jokes aside, I did see your work and it’s quite nice!

---

<div class="post-metadata">

### Author: ![Harding](https://sea2.discourse-cdn.com/flex002/user_avatar/community.hex-rays.com/harding/32/37_2.png) [@Harding](https://community.hex-rays.com/u/Harding)
#### Post date: [January 27, 2025, 3:41pm UTC](https://community.hex-rays.com/t/ida-python-ida-search-find-text-ignores-first-argument-start-ea/97/8 "2025-01-27T15:41:19Z")

</div>

> To quote Madame de Maintenon:
> 
> ```
> Friends don’t let friends use find_text().
> 
> ```

I will try to talk him out of it 😛

> okes aside, I did see your work and it’s quite nice!

Thank you! \<3
